Commit dd8aae4c authored by mikhal@webrtc.org's avatar mikhal@webrtc.org

LibYuv: Updates to general functionality.

Review URL: http://webrtc-codereview.appspot.com/219003

git-svn-id: http://libyuv.googlecode.com/svn/trunk@18 16f28f9a-4ce2-e073-06de-1de4eb20be90
parent 283eb139
...@@ -25,34 +25,31 @@ enum VideoRotationMode ...@@ -25,34 +25,31 @@ enum VideoRotationMode
{ {
kRotateNone = 0, kRotateNone = 0,
kRotateClockwise = 90, kRotateClockwise = 90,
kRotateAntiClockwise = -90, kRotateCounterClockwise = -90,
kRotate180 = 180, kRotate180 = 180,
}; };
// Mirror functions // I420 mirror
// The following 2 functions perform mirroring on an image (LeftRight/UpDown)
// Input:
// - width : Image width in pixels.
// - height : Image height in pixels.
// - inFrame : Reference to input image.
// - outFrame : Reference to converted image.
// Return value: 0 if OK, < 0 otherwise.
int int
MirrorI420LeftRight(const uint8* src_frame, int src_stride, I420Mirror(const uint8* src_yplane, int src_ystride,
uint8* dst_frame, int dst_stride, const uint8* src_uplane, int src_ustride,
int src_width, int src_height); const uint8* src_vplane, int src_vstride,
uint8* dst_yplane, int dst_ystride,
// Cut/Pad I420 frame to match desird dimensions. uint8* dst_uplane, int dst_ustride,
uint8* dst_vplane, int dst_vstride,
int width, int height);
// Crop/Pad I420 frame to match required dimensions.
int int
CutPadI420Frame(const uint8* inFrame, int inWidth, I420CropPad(const uint8* src_frame, int src_width,
int inHeight, uint8* outFrame, int src_height, uint8* dst_frame,
int outWidth, int outHeight); int dst_width, int dst_height);
// I420 Cut - make a center cut // I420 Crop - make a center cut
int int
CutI420Frame(uint8* frame, int fromWidth, I420Cut(uint8* frame,
int fromHeight, int toWidth, int src_width, int src_height,
int toHeight); int dst_width, int dst_height);
} // namespace libyuv } // namespace libyuv
......
...@@ -10,329 +10,299 @@ ...@@ -10,329 +10,299 @@
#include "general.h" #include "general.h"
#include <assert.h>
#include <string.h> // memcpy(), memset() #include <string.h> // memcpy(), memset()
#include "video_common.h"
namespace libyuv { namespace libyuv {
int int
MirrorI420LeftRight( const uint8* src_frame,uint8* dst_frame, I420Mirror(const uint8* src_yplane, int src_ystride,
int src_width, int src_height) const uint8* src_uplane, int src_ustride,
const uint8* src_vplane, int src_vstride,
uint8* dst_yplane, int dst_ystride,
uint8* dst_uplane, int dst_ustride,
uint8* dst_vplane, int dst_vstride,
int width, int height)
{ {
if (src_width < 1 || src_height < 1) if (src_yplane == NULL || src_uplane == NULL || src_vplane == NULL ||
{ dst_yplane == NULL || dst_uplane == NULL || dst_vplane == NULL)
return -1; return -1;
}
assert(src_width % 2 == 0 && src_height % 2 == 0);
int indO = 0; int indO = 0;
int indS = 0; int indS = 0;
int wind, hind; int wind, hind;
uint8 tmpVal; uint8 tmpVal, tmpValU, tmpValV;
// Will swap two values per iteration // Will swap two values per iteration
const int halfW = src_width >> 1; const int halfWidth = (width + 1) >> 1;
const int halfStride = src_width >> 1;
// Y // Y
for (wind = 0; wind < halfW; wind++ ) for (wind = 0; wind < halfWidth; wind++){
{ for (hind = 0; hind < height; hind++){
for (hind = 0; hind < src_height; hind++ ) indO = hind * src_ystride + wind;
{ indS = hind * dst_ystride + (width - wind - 1);
indO = hind * src_width + wind; tmpVal = src_yplane[indO];
indS = hind * src_width + (src_width - wind - 1); // swapping index dst_yplane[indO] = src_yplane[indS];
tmpVal = src_frame[indO]; dst_yplane[indS] = tmpVal;
dst_frame[indO] = src_frame[indS]; }
dst_frame[indS] = tmpVal; }
} // end for (height)
} // end for(width)
const int lengthW = src_width >> 2;
const int lengthH = src_height >> 1;
// V
int zeroInd = src_width * src_height;
for (wind = 0; wind < lengthW; wind++ )
{
for (hind = 0; hind < lengthH; hind++ )
{
indO = zeroInd + hind * halfW + wind;
indS = zeroInd + hind * halfW + (halfW - wind - 1);// swapping index
tmpVal = src_frame[indO];
dst_frame[indO] = src_frame[indS];
dst_frame[indS] = tmpVal;
} // end for (height)
} // end for(width)
// U const int halfHeight = (height + 1) >> 1;
zeroInd += src_width * src_height >> 2; const int halfSrcuvStride = (height + 1) >> 1;
for (wind = 0; wind < lengthW; wind++ ) const int halfuvWidth = (width + 1) >> 2;
{
for (hind = 0; hind < lengthH; hind++ )
{
indO = zeroInd + hind * halfW + wind;
indS = zeroInd + hind * halfW + (halfW - wind - 1);// swapping index
tmpVal = src_frame[indO];
dst_frame[indO] = src_frame[indS];
dst_frame[indS] = tmpVal;
} // end for (height)
} // end for(width)
for (wind = 0; wind < halfuvWidth; wind++){
for (hind = 0; hind < halfHeight; hind++){
indO = hind * halfSrcuvStride + wind;
indS = hind * halfSrcuvStride + (halfuvWidth - wind - 1);
// U
tmpValU = src_uplane[indO];
dst_uplane[indO] = src_uplane[indS];
dst_uplane[indS] = tmpValU;
// V
tmpValV = src_vplane[indO];
dst_vplane[indO] = src_vplane[indS];
dst_vplane[indS] = tmpValV;
}
}
return 0; return 0;
} }
// Make a center cut // Make a center cut
int int
CutI420Frame(uint8* frame, I420Cut(uint8* frame,
int fromWidth, int fromHeight, int src_width, int src_height,
int toWidth, int toHeight) int dst_width, int dst_height)
{ {
if (toWidth < 1 || fromWidth < 1 || toHeight < 1 || fromHeight < 1 ) if (frame == NULL)
{
return -1; return -1;
}
if (toWidth == fromWidth && toHeight == fromHeight) if (src_width == dst_width && src_height == dst_height){
{
// Nothing to do // Nothing to do
return 3 * toHeight * toWidth / 2; return 3 * dst_height * dst_width / 2;
} }
if (toWidth > fromWidth || toHeight > fromHeight) if (dst_width > src_width || dst_height > src_height){
{
// error // error
return -1; return -1;
} }
int i = 0; int i = 0;
int m = 0; int m = 0;
int loop = 0; int loop = 0;
int halfToWidth = toWidth / 2; int half_dst_width = dst_width / 2;
int halfToHeight = toHeight / 2; int halfdst_height = dst_height / 2;
int halfFromWidth = fromWidth / 2; int halfsrc_width = src_width / 2;
int halfFromHeight= fromHeight / 2; int half_dst_height= src_height / 2;
int cutHeight = ( fromHeight - toHeight ) / 2; int crop_height = ( src_height - dst_height ) / 2;
int cutWidth = ( fromWidth - toWidth ) / 2; int crop_width = ( src_width - dst_width ) / 2;
for (i = fromWidth * cutHeight + cutWidth; loop < toHeight ; for (i = src_width * crop_height + crop_width; loop < dst_height ;
loop++, i += fromWidth) loop++, i += src_width){
{ memcpy(&frame[m],&frame[i],dst_width);
memcpy(&frame[m],&frame[i],toWidth); m += dst_width;
m += toWidth;
} }
i = fromWidth * fromHeight; // ilum i = src_width * src_height; // ilum
loop = 0; loop = 0;
for ( i += (halfFromWidth * cutHeight / 2 + cutWidth / 2); for ( i += (halfsrc_width * crop_height / 2 + crop_width / 2);
loop < halfToHeight; loop++,i += halfFromWidth) loop < halfdst_height; loop++,i += halfsrc_width){
{ memcpy(&frame[m],&frame[i],half_dst_width);
memcpy(&frame[m],&frame[i],halfToWidth); m += half_dst_width;
m += halfToWidth;
} }
loop = 0; loop = 0;
i = fromWidth * fromHeight + halfFromHeight * halfFromWidth; // ilum + Cr i = src_width * src_height + half_dst_height * halfsrc_width; // ilum + Cr
for ( i += (halfFromWidth * cutHeight / 2 + cutWidth / 2); for ( i += (halfsrc_width * crop_height / 2 + crop_width / 2);
loop < halfToHeight; loop++, i += halfFromWidth) loop < halfdst_height; loop++, i += halfsrc_width){
{ memcpy(&frame[m],&frame[i],half_dst_width);
memcpy(&frame[m],&frame[i],halfToWidth); m += half_dst_width;
m += halfToWidth;
} }
return halfToWidth * toHeight * 3; return 0;
} }
int int
CutPadI420Frame(const uint8* inFrame, int inWidth, I420CropPad(const uint8* src_frame, int src_width,
int inHeight, uint8* outFrame, int src_height, uint8* dst_frame,
int outWidth, int outHeight) int dst_width, int dst_height)
{ {
if (inWidth < 1 || outWidth < 1 || inHeight < 1 || outHeight < 1 ) if (src_width < 1 || dst_width < 1 || src_height < 1 || dst_height < 1 )
{
return -1; return -1;
} if (src_width == dst_width && src_height == dst_height)
if (inWidth == outWidth && inHeight == outHeight) memcpy(dst_frame, src_frame, 3 * dst_width * (dst_height >> 1));
{
memcpy(outFrame, inFrame, 3 * outWidth * (outHeight >> 1));
}
else else
{ {
if ( inHeight < outHeight) if ( src_height < dst_height){
{
// pad height // pad height
int padH = outHeight - inHeight; int pad_height = dst_height - src_height;
int i = 0; int i = 0;
int padW = 0; int pad_width = 0;
int cutW = 0; int crop_width = 0;
int width = inWidth; int width = src_width;
if (inWidth < outWidth) if (src_width < dst_width){
{
// pad width // pad width
padW = outWidth - inWidth; pad_width = dst_width - src_width;
} } else{
else
{
// cut width // cut width
cutW = inWidth - outWidth; crop_width = src_width - dst_width;
width = outWidth; width = dst_width;
} }
if (padH) if (pad_height){
{ memset(dst_frame, 0, dst_width * (pad_height >> 1));
memset(outFrame, 0, outWidth * (padH >> 1)); dst_frame += dst_width * (pad_height >> 1);
outFrame += outWidth * (padH >> 1);
} }
for (i = 0; i < inHeight;i++) for (i = 0; i < src_height;i++)
{ {
if (padW) if (pad_width)
{ {
memset(outFrame, 0, padW / 2); memset(dst_frame, 0, pad_width / 2);
outFrame += padW / 2; dst_frame += pad_width / 2;
} }
inFrame += cutW >> 1; // in case we have a cut src_frame += crop_width >> 1; // in case we have a cut
memcpy(outFrame,inFrame ,width); memcpy(dst_frame,src_frame ,width);
inFrame += cutW >> 1; src_frame += crop_width >> 1;
outFrame += width; dst_frame += width;
inFrame += width; src_frame += width;
if (padW) if (pad_width)
{ {
memset(outFrame, 0, padW / 2); memset(dst_frame, 0, pad_width / 2);
outFrame += padW / 2; dst_frame += pad_width / 2;
} }
} }
if (padH) if (pad_height)
{ {
memset(outFrame, 0, outWidth * (padH >> 1)); memset(dst_frame, 0, dst_width * (pad_height >> 1));
outFrame += outWidth * (padH >> 1); dst_frame += dst_width * (pad_height >> 1);
} }
if (padH) if (pad_height)
{ {
memset(outFrame, 127, (outWidth >> 2) * (padH >> 1)); memset(dst_frame, 127, (dst_width >> 2) * (pad_height >> 1));
outFrame += (outWidth >> 2) * (padH >> 1); dst_frame += (dst_width >> 2) * (pad_height >> 1);
} }
for (i = 0; i < (inHeight >> 1); i++) for (i = 0; i < (src_height >> 1); i++)
{ {
if (padW) if (pad_width)
{ {
memset(outFrame, 127, padW >> 2); memset(dst_frame, 127, pad_width >> 2);
outFrame += padW >> 2; dst_frame += pad_width >> 2;
} }
inFrame += cutW >> 2; // in case we have a cut src_frame += crop_width >> 2; // in case we have a cut
memcpy(outFrame, inFrame,width >> 1); memcpy(dst_frame, src_frame,width >> 1);
inFrame += cutW >> 2; src_frame += crop_width >> 2;
outFrame += width >> 1; dst_frame += width >> 1;
inFrame += width >> 1; src_frame += width >> 1;
if (padW) if (pad_width)
{ {
memset(outFrame, 127, padW >> 2); memset(dst_frame, 127, pad_width >> 2);
outFrame += padW >> 2; dst_frame += pad_width >> 2;
} }
} }
if (padH) if (pad_height)
{ {
memset(outFrame, 127, (outWidth >> 1) * (padH >> 1)); memset(dst_frame, 127, (dst_width >> 1) * (pad_height >> 1));
outFrame += (outWidth >> 1) * (padH >> 1); dst_frame += (dst_width >> 1) * (pad_height >> 1);
} }
for (i = 0; i < (inHeight >> 1); i++) for (i = 0; i < (src_height >> 1); i++)
{ {
if (padW) if (pad_width)
{ {
memset(outFrame, 127, padW >> 2); memset(dst_frame, 127, pad_width >> 2);
outFrame += padW >> 2; dst_frame += pad_width >> 2;
} }
inFrame += cutW >> 2; // in case we have a cut src_frame += crop_width >> 2; // in case we have a cut
memcpy(outFrame, inFrame,width >> 1); memcpy(dst_frame, src_frame,width >> 1);
inFrame += cutW >> 2; src_frame += crop_width >> 2;
outFrame += width >> 1; dst_frame += width >> 1;
inFrame += width >> 1; src_frame += width >> 1;
if (padW) if (pad_width)
{ {
memset(outFrame, 127, padW >> 2); memset(dst_frame, 127, pad_width >> 2);
outFrame += padW >> 2; dst_frame += pad_width >> 2;
} }
} }
if (padH) if (pad_height)
{ {
memset(outFrame, 127, (outWidth >> 2) * (padH >> 1)); memset(dst_frame, 127, (dst_width >> 2) * (pad_height >> 1));
outFrame += (outWidth >> 2) * (padH >> 1); dst_frame += (dst_width >> 2) * (pad_height >> 1);
} }
} }
else else
{ {
// cut height // cut height
int i = 0; int i = 0;
int padW = 0; int pad_width = 0;
int cutW = 0; int crop_width = 0;
int width = inWidth; int width = src_width;
if (inWidth < outWidth) if (src_width < dst_width)
{ {
// pad width // pad width
padW = outWidth - inWidth; pad_width = dst_width - src_width;
} else } else
{ {
// cut width // cut width
cutW = inWidth - outWidth; crop_width = src_width - dst_width;
width = outWidth; width = dst_width;
} }
int diffH = inHeight - outHeight; int diff_height = src_height - dst_height;
inFrame += inWidth * (diffH >> 1); // skip top I src_frame += src_width * (diff_height >> 1); // skip top I
for (i = 0; i < outHeight; i++) for (i = 0; i < dst_height; i++)
{ {
if (padW) if (pad_width)
{ {
memset(outFrame, 0, padW / 2); memset(dst_frame, 0, pad_width / 2);
outFrame += padW / 2; dst_frame += pad_width / 2;
} }
inFrame += cutW >> 1; // in case we have a cut src_frame += crop_width >> 1; // in case we have a cut
memcpy(outFrame,inFrame ,width); memcpy(dst_frame,src_frame ,width);
inFrame += cutW >> 1; src_frame += crop_width >> 1;
outFrame += width; dst_frame += width;
inFrame += width; src_frame += width;
if (padW) if (pad_width)
{ {
memset(outFrame, 0, padW / 2); memset(dst_frame, 0, pad_width / 2);
outFrame += padW / 2; dst_frame += pad_width / 2;
} }
} }
inFrame += inWidth * (diffH >> 1); // skip end I src_frame += src_width * (diff_height >> 1); // skip end I
inFrame += (inWidth >> 2) * (diffH >> 1); // skip top of Cr src_frame += (src_width >> 2) * (diff_height >> 1); // skip top of Cr
for (i = 0; i < (outHeight >> 1); i++) for (i = 0; i < (dst_height >> 1); i++)
{ {
if (padW) if (pad_width)
{ {
memset(outFrame, 127, padW >> 2); memset(dst_frame, 127, pad_width >> 2);
outFrame += padW >> 2; dst_frame += pad_width >> 2;
} }
inFrame += cutW >> 2; // in case we have a cut src_frame += crop_width >> 2; // in case we have a cut
memcpy(outFrame, inFrame,width >> 1); memcpy(dst_frame, src_frame,width >> 1);
inFrame += cutW >> 2; src_frame += crop_width >> 2;
outFrame += width >> 1; dst_frame += width >> 1;
inFrame += width >> 1; src_frame += width >> 1;
if (padW) if (pad_width)
{ {
memset(outFrame, 127, padW >> 2); memset(dst_frame, 127, pad_width >> 2);
outFrame += padW >> 2; dst_frame += pad_width >> 2;
} }
} }
inFrame += (inWidth >> 2) * (diffH >> 1); // skip end of Cr src_frame += (src_width >> 2) * (diff_height >> 1); // skip end of Cr
inFrame += (inWidth >> 2) * (diffH >> 1); // skip top of Cb src_frame += (src_width >> 2) * (diff_height >> 1); // skip top of Cb
for (i = 0; i < (outHeight >> 1); i++) for (i = 0; i < (dst_height >> 1); i++)
{ {
if (padW) if (pad_width)
{ {
memset(outFrame, 127, padW >> 2); memset(dst_frame, 127, pad_width >> 2);
outFrame += padW >> 2; dst_frame += pad_width >> 2;
} }
inFrame += cutW >> 2; // in case we have a cut src_frame += crop_width >> 2; // in case we have a cut
memcpy(outFrame, inFrame, width >> 1); memcpy(dst_frame, src_frame, width >> 1);
inFrame += cutW >> 2; src_frame += crop_width >> 2;
outFrame += width >> 1; dst_frame += width >> 1;
inFrame += width >> 1; src_frame += width >> 1;
if (padW) if (pad_width)
{ {
memset(outFrame, 127, padW >> 2); memset(dst_frame, 127, pad_width >> 2);
outFrame += padW >> 2; dst_frame += pad_width >> 2;
} }
} }
} }
} }
return 3 * outWidth * (outHeight >> 1); return 0;
} }
} // nmaespace libyuv } // nmaespace libyuv
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