[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