Commit 7b748aff authored by Luca Abeni's avatar Luca Abeni

Introduce swscale interface in libavcodec

Originally committed as revision 5266 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 703c8195
......@@ -23,6 +23,7 @@
*/
#include "avcodec.h"
#include "swscale.h"
#include "dsputil.h"
#ifdef USE_FASTMEMCPY
......@@ -630,6 +631,140 @@ void img_resample_close(ImgReSampleContext *s)
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 == NULL) {
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->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);
}
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 < 3; 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;
}
}
the_end:
av_free(buf1);
av_free(buf2);
return res;
}
#ifdef TEST
#include <stdio.h>
......
#ifndef SWSCALE_EMU_H
#define SWSCALE_EMU_H
/* Dummy, only useful for compilation! */
#define SWS_FAST_BILINEAR 1
#define SWS_BILINEAR 2
#define SWS_BICUBIC 4
#define SWS_X 8
#define SWS_POINT 0x10
#define SWS_AREA 0x20
#define SWS_BICUBLIN 0x40
#define SWS_GAUSS 0x80
#define SWS_SINC 0x100
#define SWS_LANCZOS 0x200
#define SWS_SPLINE 0x400
#define SwsFilter void
struct SwsContext {
struct ImgReSampleContext *resampling_ctx;
enum PixelFormat src_pix_fmt, dst_pix_fmt;
};
struct SwsContext *sws_getContext(int srcW, int srcH, int srcFormat,
int dstW, int dstH, int dstFormat,
int flags, SwsFilter *srcFilter,
SwsFilter *dstFilter, double *param);
int sws_scale(struct SwsContext *ctx, uint8_t* src[], int srcStride[],
int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]);
void sws_freeContext(struct SwsContext *swsContext);
static inline void sws_global_init(void *(*alloc)(unsigned int size),
void (*free)(void *ptr),
void (*log)(void*, int level, const char *fmt, ...))
{
}
#endif /* SWSCALE_EMU_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment