Commit 655f688d authored by Jindřich Makovička's avatar Jindřich Makovička

support for negative strides

Originally committed as revision 3989 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent c80d990f
...@@ -1051,18 +1051,20 @@ void pp_postprocess(uint8_t * src[3], int srcStride[3], ...@@ -1051,18 +1051,20 @@ void pp_postprocess(uint8_t * src[3], int srcStride[3],
int mbHeight= (height+15)>>4; int mbHeight= (height+15)>>4;
PPMode *mode = (PPMode*)vm; PPMode *mode = (PPMode*)vm;
PPContext *c = (PPContext*)vc; PPContext *c = (PPContext*)vc;
int minStride= MAX(srcStride[0], dstStride[0]); int minStride= MAX(ABS(srcStride[0]), ABS(dstStride[0]));
int absQPStride = ABS(QPStride);
if(c->stride < minStride || c->qpStride < QPStride) // c->stride and c->QPStride are always positive
if(c->stride < minStride || c->qpStride < absQPStride)
reallocBuffers(c, width, height, reallocBuffers(c, width, height,
MAX(minStride, c->stride), MAX(minStride, c->stride),
MAX(c->qpStride, QPStride)); MAX(c->qpStride, absQPStride));
if(QP_store==NULL || (mode->lumMode & FORCE_QUANT)) if(QP_store==NULL || (mode->lumMode & FORCE_QUANT))
{ {
int i; int i;
QP_store= c->forcedQPTable; QP_store= c->forcedQPTable;
QPStride= 0; absQPStride = QPStride = 0;
if(mode->lumMode & FORCE_QUANT) if(mode->lumMode & FORCE_QUANT)
for(i=0; i<mbWidth; i++) QP_store[i]= mode->forcedQuant; for(i=0; i<mbWidth; i++) QP_store[i]= mode->forcedQuant;
else else
...@@ -1072,7 +1074,7 @@ void pp_postprocess(uint8_t * src[3], int srcStride[3], ...@@ -1072,7 +1074,7 @@ void pp_postprocess(uint8_t * src[3], int srcStride[3],
if(pict_type & PP_PICT_TYPE_QP2){ if(pict_type & PP_PICT_TYPE_QP2){
int i; int i;
const int count= mbHeight * QPStride; const int count= mbHeight * absQPStride;
for(i=0; i<(count>>2); i++){ for(i=0; i<(count>>2); i++){
((uint32_t*)c->stdQPTable)[i] = (((uint32_t*)QP_store)[i]>>1) & 0x7F7F7F7F; ((uint32_t*)c->stdQPTable)[i] = (((uint32_t*)QP_store)[i]>>1) & 0x7F7F7F7F;
} }
...@@ -1080,6 +1082,7 @@ void pp_postprocess(uint8_t * src[3], int srcStride[3], ...@@ -1080,6 +1082,7 @@ void pp_postprocess(uint8_t * src[3], int srcStride[3],
c->stdQPTable[i] = QP_store[i]>>1; c->stdQPTable[i] = QP_store[i]>>1;
} }
QP_store= c->stdQPTable; QP_store= c->stdQPTable;
QPStride= absQPStride;
} }
if(0){ if(0){
...@@ -1095,6 +1098,7 @@ for(y=0; y<mbHeight; y++){ ...@@ -1095,6 +1098,7 @@ for(y=0; y<mbHeight; y++){
if((pict_type&7)!=3) if((pict_type&7)!=3)
{ {
if (QPStride >= 0) {
int i; int i;
const int count= mbHeight * QPStride; const int count= mbHeight * QPStride;
for(i=0; i<(count>>2); i++){ for(i=0; i<(count>>2); i++){
...@@ -1103,6 +1107,14 @@ for(y=0; y<mbHeight; y++){ ...@@ -1103,6 +1107,14 @@ for(y=0; y<mbHeight; y++){
for(i<<=2; i<count; i++){ for(i<<=2; i<count; i++){
c->nonBQPTable[i] = QP_store[i] & 0x3F; c->nonBQPTable[i] = QP_store[i] & 0x3F;
} }
} else {
int i,j;
for(i=0; i<mbHeight; i++) {
for(j=0; j<absQPStride; j++) {
c->nonBQPTable[i*absQPStride+j] = QP_store[i*QPStride+j] & 0x3F;
}
}
}
} }
if(verbose>2) if(verbose>2)
...@@ -1125,8 +1137,8 @@ for(y=0; y<mbHeight; y++){ ...@@ -1125,8 +1137,8 @@ for(y=0; y<mbHeight; y++){
} }
else if(srcStride[1] == dstStride[1] && srcStride[2] == dstStride[2]) else if(srcStride[1] == dstStride[1] && srcStride[2] == dstStride[2])
{ {
memcpy(dst[1], src[1], srcStride[1]*height); linecpy(dst[1], src[1], height, srcStride[1]);
memcpy(dst[2], src[2], srcStride[2]*height); linecpy(dst[2], src[2], height, srcStride[2]);
} }
else else
{ {
......
...@@ -160,3 +160,11 @@ typedef struct PPContext{ ...@@ -160,3 +160,11 @@ typedef struct PPContext{
} PPContext; } PPContext;
static inline void linecpy(void *dest, void *src, int lines, int stride)
{
if (stride > 0) {
memcpy(dest, src, lines*stride);
} else {
memcpy(dest+(lines-1)*stride, src+(lines-1)*stride, -lines*stride);
}
}
...@@ -3366,8 +3366,8 @@ static void RENAME(postProcess)(uint8_t src[], int srcStride, uint8_t dst[], int ...@@ -3366,8 +3366,8 @@ static void RENAME(postProcess)(uint8_t src[], int srcStride, uint8_t dst[], int
//FIXME remove //FIXME remove
uint64_t * const yHistogram= c.yHistogram; uint64_t * const yHistogram= c.yHistogram;
uint8_t * const tempSrc= c.tempSrc; uint8_t * const tempSrc= srcStride > 0 ? c.tempSrc : c.tempSrc - 23*srcStride;
uint8_t * const tempDst= c.tempDst; uint8_t * const tempDst= dstStride > 0 ? c.tempDst : c.tempDst - 23*dstStride;
//const int mbWidth= isColor ? (width+7)>>3 : (width+15)>>4; //const int mbWidth= isColor ? (width+7)>>3 : (width+15)>>4;
#ifdef HAVE_MMX #ifdef HAVE_MMX
...@@ -3529,8 +3529,8 @@ static void RENAME(postProcess)(uint8_t src[], int srcStride, uint8_t dst[], int ...@@ -3529,8 +3529,8 @@ static void RENAME(postProcess)(uint8_t src[], int srcStride, uint8_t dst[], int
dstBlock+=8; dstBlock+=8;
srcBlock+=8; srcBlock+=8;
} }
if(width==dstStride) if(width==ABS(dstStride))
memcpy(dst, tempDst + 9*dstStride, copyAhead*dstStride); linecpy(dst, tempDst + 9*dstStride, copyAhead, dstStride);
else else
{ {
int i; int i;
...@@ -3552,7 +3552,7 @@ static void RENAME(postProcess)(uint8_t src[], int srcStride, uint8_t dst[], int ...@@ -3552,7 +3552,7 @@ static void RENAME(postProcess)(uint8_t src[], int srcStride, uint8_t dst[], int
uint8_t *tempBlock2= c.tempBlocks + 8; uint8_t *tempBlock2= c.tempBlocks + 8;
#endif #endif
int8_t *QPptr= &QPs[(y>>qpVShift)*QPStride]; int8_t *QPptr= &QPs[(y>>qpVShift)*QPStride];
int8_t *nonBQPptr= &c.nonBQPTable[(y>>qpVShift)*QPStride]; int8_t *nonBQPptr= &c.nonBQPTable[(y>>qpVShift)*ABS(QPStride)];
int QP=0; int QP=0;
/* can we mess with a 8x16 block from srcBlock/dstBlock downwards and 1 line upwards /* can we mess with a 8x16 block from srcBlock/dstBlock downwards and 1 line upwards
if not than use a temporary buffer */ if not than use a temporary buffer */
...@@ -3561,19 +3561,19 @@ static void RENAME(postProcess)(uint8_t src[], int srcStride, uint8_t dst[], int ...@@ -3561,19 +3561,19 @@ static void RENAME(postProcess)(uint8_t src[], int srcStride, uint8_t dst[], int
int i; int i;
/* copy from line (copyAhead) to (copyAhead+7) of src, these will be copied with /* copy from line (copyAhead) to (copyAhead+7) of src, these will be copied with
blockcopy to dst later */ blockcopy to dst later */
memcpy(tempSrc + srcStride*copyAhead, srcBlock + srcStride*copyAhead, linecpy(tempSrc + srcStride*copyAhead, srcBlock + srcStride*copyAhead,
srcStride*MAX(height-y-copyAhead, 0) ); MAX(height-y-copyAhead, 0), srcStride);
/* duplicate last line of src to fill the void upto line (copyAhead+7) */ /* duplicate last line of src to fill the void upto line (copyAhead+7) */
for(i=MAX(height-y, 8); i<copyAhead+8; i++) for(i=MAX(height-y, 8); i<copyAhead+8; i++)
memcpy(tempSrc + srcStride*i, src + srcStride*(height-1), srcStride); memcpy(tempSrc + srcStride*i, src + srcStride*(height-1), ABS(srcStride));
/* copy up to (copyAhead+1) lines of dst (line -1 to (copyAhead-1))*/ /* copy up to (copyAhead+1) lines of dst (line -1 to (copyAhead-1))*/
memcpy(tempDst, dstBlock - dstStride, dstStride*MIN(height-y+1, copyAhead+1) ); linecpy(tempDst, dstBlock - dstStride, MIN(height-y+1, copyAhead+1), dstStride);
/* duplicate last line of dst to fill the void upto line (copyAhead) */ /* duplicate last line of dst to fill the void upto line (copyAhead) */
for(i=height-y+1; i<=copyAhead; i++) for(i=height-y+1; i<=copyAhead; i++)
memcpy(tempDst + dstStride*i, dst + dstStride*(height-1), dstStride); memcpy(tempDst + dstStride*i, dst + dstStride*(height-1), ABS(dstStride));
dstBlock= tempDst + dstStride; dstBlock= tempDst + dstStride;
srcBlock= tempSrc; srcBlock= tempSrc;
...@@ -3785,8 +3785,8 @@ static void RENAME(postProcess)(uint8_t src[], int srcStride, uint8_t dst[], int ...@@ -3785,8 +3785,8 @@ static void RENAME(postProcess)(uint8_t src[], int srcStride, uint8_t dst[], int
if(y+15 >= height) if(y+15 >= height)
{ {
uint8_t *dstBlock= &(dst[y*dstStride]); uint8_t *dstBlock= &(dst[y*dstStride]);
if(width==dstStride) if(width==ABS(dstStride))
memcpy(dstBlock, tempDst + dstStride, dstStride*(height-y)); linecpy(dstBlock, tempDst + dstStride, height-y, dstStride);
else else
{ {
int i; int i;
......
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