int video_decoder::swscale(const char* srcbuf, int ntype, int nsrcwidth, int nsrcheight, int ndstwidth, int ndstheight, unsigned char* dstbuf)
{
if (5 != ntype && 3 != ntype)
{
return -1;
}
if (!srcbuf || !dstbuf)
return -1;
AVPixelFormat srcpixfmt = AV_PIX_FMT_YUV420P;
AVPixelFormat dstpixfmt = AV_PIX_FMT_BGR32;
uint8_t* src_y = 0;
uint8_t* src_u = 0;
uint8_t* src_v = 0;
if (3 == ntype)
{
src_y = (uint8_t*)srcbuf;
src_v = (uint8_t*)srcbuf + nsrcwidth * nsrcheight;
src_u = (uint8_t*)srcbuf + nsrcwidth * nsrcheight + nsrcwidth * nsrcheight / 4;
}
else
{
src_y = (uint8_t*)srcbuf;
src_u = (uint8_t*)srcbuf + nsrcwidth * nsrcheight;
src_v = (uint8_t*)srcbuf + nsrcwidth * nsrcheight + nsrcwidth * nsrcheight / 4;
}
uint8_t* src[3] = { src_y, src_v, src_u };
int srcstride[3] = { nsrcwidth, nsrcwidth / 2, nsrcwidth / 2 };
srcstride[0] = nsrcwidth;
srcstride[1] = nsrcwidth / 2;
srcstride[2] = nsrcwidth / 2;
src[0] += srcstride[0] * (nsrcheight - 1);
srcstride[0] *= -1;
src[1] += srcstride[1] * (nsrcheight / 2 - 1);
srcstride[1] *= -1;
src[2] += srcstride[2] * (nsrcheight / 2 - 1);
srcstride[2] *= -1;
uint8_t* dst[4] = { dstbuf, NULL, NULL, NULL };
int dststride[4] = { ndstwidth * 4, 0, 0, 0 };
SwsContext* s = sws_getContext(nsrcwidth, nsrcheight, srcpixfmt, ndstwidth, ndstheight, dstpixfmt, SWS_BICUBIC, NULL, NULL, NULL);
if (NULL == s)
{
return 0;
}
sws_scale(s, src, srcstride, 0, nsrcheight, dst, dststride);
sws_freeContext(s);
return 0;
}