[FFmpeg-devel] [code] Wrapper for img_resample using swscale internal primitive

Cyril Russo stage.nexvision
Tue Dec 9 18:20:25 CET 2008


Hi all,

  Here's the implementation of old img_resample functions using 
sws_scale primitives.

As usual, I don't care about the comma not been at the right place, and 
so on.
So use it if you only need a simple solution that works.
Patch are welcome to make it fit Mickael's conventions (the code below 
is public domain).
BTW, no wrapper for img_convert yet.

In my implementation (not included) I've added an img_resample_update 
method
to reallocate the ImgReSampleContext only if required (if the input's or 
output's size changes, but not when the crop'ed window moves)
That's why I store the output image's size in the context (not required 
in the implementation below, but doesn't break anything).

---------------------------------- resampleWrapper.h ---------
#include "avcodec.h"
#include "swscale.h"
#if LIBAVCODEC_VERSION_MAJOR >= 52
    // Starting from this version, ImgReSampleContext doesn't exist 
anymore.
    // This code implements the previous functions with a similar interface
    struct ImgReSampleContext
    {
        /** The context used for resizing */
        SwsContext *    context;
        /** The source's width */
        int             width;
        /** The source's height */
        int             height;
        /** The banding used */
        int             bandLeft;
        /** The banding used */
        int             bandRight;
        /** The banding used */
        int             bandTop;
        /** The banding used */
        int             bandBottom;
        /** The padding used */
        int             padLeft;
        /** The padding used */
        int             padRight;
        /** The padding used */
        int             padTop;
        /** The padding used */
        int             padBottom;
        /** The output width */
        int             outWidth;
        /** The output height */
        int             outHeight;
    };

void img_resample_close(ImgReSampleContext * s);
void img_resample(ImgReSampleContext * context, AVPicture * out, const 
AVPicture * in);
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 * img_resample_init (int owidth, int oheight, int 
iwidth, int iheight);
#endif

---------------------------------- resampleWrapper.c ---------

#if LIBAVCODEC_VERSION_MAJOR >= 52



    void img_resample(ImgReSampleContext * context, AVPicture * pxOut, 
const AVPicture * pxIn)
    {
        if (context != NULL && context->context != NULL)
        {
            AVPicture shiftedInput = {0};
            shiftedInput.data[0] = pxIn->data[0] + pxIn->linesize[0] * 
context->bandTop + context->bandLeft;
            shiftedInput.data[1] = pxIn->data[1] + (pxIn->linesize[1] * 
(context->bandTop / 2)) + (context->bandLeft+1) / 2;
            shiftedInput.data[2] = pxIn->data[2] + (pxIn->linesize[2] * 
(context->bandTop / 2)) + (context->bandLeft+1) / 2;
            shiftedInput.linesize[0] = pxIn->linesize[0];
            shiftedInput.linesize[1] = pxIn->linesize[1];
            shiftedInput.linesize[2] = pxIn->linesize[2];
            sws_scale(context->context, (uint8_t**)shiftedInput.data, 
(int*)shiftedInput.linesize, 0, context->height - context->bandBottom - 
context->bandTop, pxOut->data, pxOut->linesize);
        }
    }
   


    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 = (ImgReSampleContext 
*)av_malloc(sizeof(ImgReSampleContext));
        if (s == NULL) return NULL;
        int srcSurface = (iwidth - rightBand - leftBand)* (iheight - 
topBand - bottomBand);
        // We use bilinear when the source surface is big, and bicubic 
when the number of pixels to handle is less than 1 MPixels
        s->context = sws_getContext(iwidth - rightBand - leftBand, 
iheight - topBand - bottomBand, PIX_FMT_YUV420P, owidth, oheight, 
PIX_FMT_YUV420P, srcSurface > 1024000 ? SWS_FAST_BILINEAR : SWS_BICUBIC, 
NULL, NULL, NULL);
        if (s->context == NULL) { av_free(s); return NULL; }
        s->bandLeft = leftBand;
        s->bandRight = rightBand;
        s->bandTop = topBand;
        s->bandBottom = bottomBand;

        s->padLeft = padleft;
        s->padRight = padright;
        s->padTop = padtop;
        s->padBottom = padbottom;

        s->width = iwidth;
        s->height = iheight;

        s->outWidth = owidth;
        s->outHeight = oheight;

        return s;
    }

    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);
    }

    void img_resample_close(ImgReSampleContext * s)
    {
        if (s == NULL) return;
        sws_freeContext(s->context);

        av_free(s);   
    }

#endif






More information about the ffmpeg-devel mailing list