Skip to content
This repository has been archived by the owner on Jun 4, 2023. It is now read-only.

Commit

Permalink
swscale: process horizontal lines in batches
Browse files Browse the repository at this point in the history
Process more lines in a single pass to improve performance

Signed-off-by: Michael Niedermayer <[email protected]>
  • Loading branch information
grandao authored and michaelni committed Aug 17, 2015
1 parent e0a3173 commit 737aa90
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 16 deletions.
4 changes: 2 additions & 2 deletions libswscale/slice.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,12 +224,12 @@ int ff_init_filters(SwsContext * c)
res = alloc_slice(&c->slice[0], c->srcFormat, c->srcH, c->chrSrcH, c->chrSrcHSubSample, c->chrSrcVSubSample, 0);
if (res < 0) goto cleanup;
for (i = 1; i < c->numSlice-1; ++i) {
res = alloc_slice(&c->slice[i], c->srcFormat, c->vLumFilterSize, c->vChrFilterSize, c->chrSrcHSubSample, c->chrSrcVSubSample, 0);
res = alloc_slice(&c->slice[i], c->srcFormat, c->vLumFilterSize + MAX_LINES_AHEAD, c->vChrFilterSize + MAX_LINES_AHEAD, c->chrSrcHSubSample, c->chrSrcVSubSample, 0);
if (res < 0) goto cleanup;
res = alloc_lines(&c->slice[i], FFALIGN(c->srcW*2+78, 16), c->srcW);
if (res < 0) goto cleanup;
}
res = alloc_slice(&c->slice[i], c->srcFormat, c->vLumFilterSize, c->vChrFilterSize, c->chrDstHSubSample, c->chrDstVSubSample, 1);
res = alloc_slice(&c->slice[i], c->srcFormat, c->vLumFilterSize + MAX_LINES_AHEAD, c->vChrFilterSize + MAX_LINES_AHEAD, c->chrDstHSubSample, c->chrDstVSubSample, 1);
if (res < 0) goto cleanup;
res = alloc_lines(&c->slice[i], dst_stride, c->dstW);
if (res < 0) goto cleanup;
Expand Down
57 changes: 44 additions & 13 deletions libswscale/swscale.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,8 @@ static int swscale(SwsContext *c, const uint8_t *src[],
SwsSlice *src_slice = &c->slice[lumStart];
SwsSlice *dst_slice = &c->slice[c->numSlice-1];
SwsFilterDescriptor *desc = c->desc;
int hasLumHoles = 1;
int hasChrHoles = 1;


if (!usePal(c->srcFormat)) {
Expand Down Expand Up @@ -487,21 +489,28 @@ static int swscale(SwsContext *c, const uint8_t *src[],
int lastChrSrcY = FFMIN(c->chrSrcH, firstChrSrcY + vChrFilterSize) - 1;
int enough_lines;
int i;
int posY, cPosY, firstPosY, lastPosY, firstCPosY, lastCPosY;

// handle holes (FAST_BILINEAR & weird filters)
if (firstLumSrcY > lastInLumBuf) {
hasLumHoles = lastInLumBuf != firstLumSrcY - 1;
lastInLumBuf = firstLumSrcY - 1;
dst_slice->plane[0].sliceY = lastInLumBuf + 1;
dst_slice->plane[3].sliceY = lastInLumBuf + 1;
dst_slice->plane[0].sliceH =
dst_slice->plane[3].sliceH = 0;
if (hasLumHoles) {
dst_slice->plane[0].sliceY = lastInLumBuf + 1;
dst_slice->plane[3].sliceY = lastInLumBuf + 1;
dst_slice->plane[0].sliceH =
dst_slice->plane[3].sliceH = 0;
}
}
if (firstChrSrcY > lastInChrBuf) {
hasChrHoles = lastInChrBuf != firstChrSrcY - 1;
lastInChrBuf = firstChrSrcY - 1;
dst_slice->plane[1].sliceY = lastInChrBuf + 1;
dst_slice->plane[2].sliceY = lastInChrBuf + 1;
dst_slice->plane[1].sliceH =
dst_slice->plane[2].sliceH = 0;
if (hasChrHoles) {
dst_slice->plane[1].sliceY = lastInChrBuf + 1;
dst_slice->plane[2].sliceY = lastInChrBuf + 1;
dst_slice->plane[1].sliceH =
dst_slice->plane[2].sliceH = 0;
}
}
av_assert0(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1);
av_assert0(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1);
Expand All @@ -524,17 +533,39 @@ static int swscale(SwsContext *c, const uint8_t *src[],
}

#if NEW_FILTER
ff_rotate_slice(dst_slice, lastLumSrcY, lastChrSrcY);
posY = dst_slice->plane[0].sliceY + dst_slice->plane[0].sliceH;
if (posY <= lastLumSrcY && !hasLumHoles) {
firstPosY = FFMAX(firstLumSrcY, posY);
lastPosY = FFMIN(lastLumSrcY + MAX_LINES_AHEAD, srcSliceY + srcSliceH - 1);
} else {
firstPosY = lastInLumBuf + 1;
lastPosY = lastLumSrcY;
}

cPosY = dst_slice->plane[1].sliceY + dst_slice->plane[1].sliceH;
if (cPosY <= lastChrSrcY && !hasChrHoles) {
firstCPosY = FFMAX(firstChrSrcY, cPosY);
lastCPosY = FFMIN(lastChrSrcY + MAX_LINES_AHEAD, FF_CEIL_RSHIFT(srcSliceY + srcSliceH, c->chrSrcVSubSample) - 1);
} else {
firstCPosY = lastInChrBuf + 1;
lastCPosY = lastChrSrcY;
}

ff_rotate_slice(dst_slice, lastPosY, lastCPosY);

if (lastInLumBuf < lastLumSrcY)
if (posY < lastLumSrcY + 1) {
for (i = lumStart; i < lumEnd; ++i)
desc[i].process(c, &desc[i], lastInLumBuf + 1, lastLumSrcY - lastInLumBuf);
desc[i].process(c, &desc[i], firstPosY, lastPosY - firstPosY + 1);
}

lumBufIndex += lastLumSrcY - lastInLumBuf;
lastInLumBuf = lastLumSrcY;

if (lastInChrBuf < lastChrSrcY)
if (cPosY < lastChrSrcY + 1) {
for (i = chrStart; i < chrEnd; ++i)
desc[i].process(c, &desc[i], lastInChrBuf + 1, lastChrSrcY - lastInChrBuf);
desc[i].process(c, &desc[i], firstCPosY, lastCPosY - firstCPosY + 1);
}

chrBufIndex += lastChrSrcY - lastInChrBuf;
lastInChrBuf = lastChrSrcY;

Expand Down
4 changes: 3 additions & 1 deletion libswscale/swscale_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1019,7 +1019,6 @@ int ff_free_filters(SwsContext *c);
*/
int ff_rotate_slice(SwsSlice *s, int lum, int chr);


/// initializes lum pixel format conversion descriptor
int ff_init_desc_fmt_convert(SwsFilterDescriptor *desc, SwsSlice * src, SwsSlice *dst, uint32_t *pal);

Expand All @@ -1034,4 +1033,7 @@ int ff_init_desc_chscale(SwsFilterDescriptor *desc, SwsSlice *src, SwsSlice *dst

int ff_init_desc_no_chr(SwsFilterDescriptor *desc, SwsSlice * src, SwsSlice *dst);

//number of extra lines to process
#define MAX_LINES_AHEAD 4

#endif /* SWSCALE_SWSCALE_INTERNAL_H */

0 comments on commit 737aa90

Please sign in to comment.