Commit 43575c8f authored by mikhal@webrtc.org's avatar mikhal@webrtc.org

Libyuv: Numerous changes

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

git-svn-id: http://libyuv.googlecode.com/svn/trunk@22 16f28f9a-4ce2-e073-06de-1de4eb20be90
parent abe14f80
...@@ -14,128 +14,96 @@ ...@@ -14,128 +14,96 @@
#include "basic_types.h" #include "basic_types.h"
namespace libyuv namespace libyuv {
{
class Convert {
public:
static int
I420ToRGB24(const uint8* src_yplane, int src_ystride,
const uint8* src_uplane, int src_ustride,
const uint8* src_vplane, int src_vstride,
uint8* dst_frame, int dst_stride,
int src_width, int src_height);
static int
I420ToARGB(const uint8* src_yplane, int src_ystride,
const uint8* src_uplane, int src_ustride,
const uint8* src_vplane, int src_vstride,
uint8* dst_frame, int dst_stride,
int src_width, int src_height);
static int int
I420ToARGB4444(const uint8* src_yplane, int src_ystride, I420ToRGB24(const uint8* src_yplane, int src_ystride,
const uint8* src_uplane, int src_ustride, const uint8* src_uplane, int src_ustride,
const uint8* src_vplane, int src_vstride, const uint8* src_vplane, int src_vstride,
uint8* dst_frame, int dst_stride, uint8* dst_frame, int dst_stride,
int src_width, int src_height); int src_width, int src_height);
static int int
I420ToRGB565(const uint8* src_yplane, int src_ystride, I420ToARGB4444(const uint8* src_yplane, int src_ystride,
const uint8* src_uplane, int src_ustride, const uint8* src_uplane, int src_ustride,
const uint8* src_vplane, int src_vstride, const uint8* src_vplane, int src_vstride,
uint8* dst_frame, int dst_stride, uint8* dst_frame, int dst_stride,
int src_width, int src_height); int src_width, int src_height);
static int int
I420ToARGB1555(const uint8* src_yplane, int src_ystride, I420ToRGB565(const uint8* src_yplane, int src_ystride,
const uint8* src_uplane, int src_ustride,
const uint8* src_vplane, int src_vstride,
uint8* dst_frame, int dst_stride,
int src_width, int src_height);
static int
I420ToYUY2(const uint8* src_yplane, int src_ystride,
const uint8* src_uplane, int src_ustride, const uint8* src_uplane, int src_ustride,
const uint8* src_vplane, int src_vstride, const uint8* src_vplane, int src_vstride,
uint8* dst_frame, int dst_stride, uint8* dst_frame, int dst_stride,
int src_width, int src_height); int src_width, int src_height);
static int int
I420ToUYVY(const uint8* src_yplane, int src_ystride, I420ToARGB1555(const uint8* src_yplane, int src_ystride,
const uint8* src_uplane, int src_ustride, const uint8* src_uplane, int src_ustride,
const uint8* src_vplane, int src_vstride, const uint8* src_vplane, int src_vstride,
uint8* dst_frame, int dst_stride, uint8* dst_frame, int dst_stride,
int src_width, int src_height); int src_width, int src_height);
static int
UYVYToI420(const uint8* src_frame, int src_stride,
uint8* dst_yplane, int dst_ystride,
uint8* dst_uplane, int dst_ustride,
uint8* dst_vplane, int dst_vstride,
int src_width, int src_height);
static int
RGB24ToARGB(const uint8* src_frame, int src_stride,
uint8* dst_frame, int dst_stride,
int src_width, int src_height);
static int int
RGB24ToI420(const uint8* src_frame, int src_stride, I420ToYUY2(const uint8* src_yplane, int src_ystride,
uint8* dst_yplane, int dst_ystride, const uint8* src_uplane, int src_ustride,
uint8* dst_uplane, int dst_ustride, const uint8* src_vplane, int src_vstride,
uint8* dst_vplane, int dst_vstride, uint8* dst_frame, int dst_stride,
int src_width, int src_height); int src_width, int src_height);
int
I420ToUYVY(const uint8* src_yplane, int src_ystride,
const uint8* src_uplane, int src_ustride,
const uint8* src_vplane, int src_vstride,
uint8* dst_frame, int dst_stride,
int src_width, int src_height);
int
RGB24ToARGB(const uint8* src_frame, int src_stride,
uint8* dst_frame, int dst_stride,
int src_width, int src_height);
static int int
RAWToI420(const uint8* src_frame, int src_stride, RGB24ToI420(const uint8* src_frame, int src_stride,
uint8* dst_yplane, int dst_ystride, uint8* dst_yplane, int dst_ystride,
uint8* dst_uplane, int dst_ustride, uint8* dst_uplane, int dst_ustride,
uint8* dst_vplane, int dst_vstride, uint8* dst_vplane, int dst_vstride,
int src_width, int src_height); int src_width, int src_height);
static int int
ABGRToI420(const uint8* src_frame, int src_stride, RAWToI420(const uint8* src_frame, int src_stride,
uint8* dst_yplane, int dst_ystride, uint8* dst_yplane, int dst_ystride,
uint8* dst_uplane, int dst_ustride, uint8* dst_uplane, int dst_ustride,
uint8* dst_vplane, int dst_vstride, uint8* dst_vplane, int dst_vstride,
int src_width, int src_height); int src_width, int src_height);
static int int
I420ToABGR(const uint8* src_yplane, int src_ystride, ABGRToI420(const uint8* src_frame, int src_stride,
const uint8* src_uplane, int src_ustride, uint8* dst_yplane, int dst_ystride,
const uint8* src_vplane, int src_vstride, uint8* dst_uplane, int dst_ustride,
uint8* dst_frame, int dst_stride, uint8* dst_vplane, int dst_vstride,
int src_width, int src_height); int src_width, int src_height);
static int int
I420ToBGRA(const uint8* src_yplane, int src_ystride, BGRAToI420(const uint8* src_frame, int src_stride,
const uint8* src_uplane, int src_ustride, uint8* dst_yplane, int dst_ystride,
const uint8* src_vplane, int src_vstride, uint8* dst_uplane, int dst_ustride,
uint8* dst_vplane, int dst_vstride,
int src_width, int src_height);
int
ARGBToI420(const uint8* src_frame, int src_stride,
uint8* dst_yplane, int dst_ystride,
uint8* dst_uplane, int dst_ustride,
uint8* dst_vplane, int dst_vstride,
int src_width, int src_height);
int
NV12ToRGB565(const uint8* src_yplane, int src_ystride,
const uint8* src_uvplane, int src_uvstride,
uint8* dst_frame, int dst_stride, uint8* dst_frame, int dst_stride,
int src_width, int src_height); int src_width, int src_height);
static int`
BGRAToI420(const uint8* src_frame, int src_stride,
uint8* dst_yplane, int dst_ystride,
uint8* dst_uplane, int dst_ustride,
uint8* dst_vplane, int dst_vstride,
int src_width, int src_height);
int static
ARGBToI420(const uint8* src_frame, int src_stride,
uint8* dst_yplane, int dst_ystride,
uint8* dst_uplane, int dst_ustride,
uint8* dst_vplane, int dst_vstride,
int src_width, int src_height);
static int
NV12ToRGB565(const uint8* src_yplane, int src_ystride,
const uint8* src_uvplane, int src_uvstride,
uint8* dst_frame, int dst_stride,
int src_width, int src_height);
DISALLOW_IMPLICIT_CONSTRUCTORS(Convert);
};
} // namespace libyuv } // namespace libyuv
#endif // LIBYUV_INCLUDE_CONVERT_H_ #endif // LIBYUV_INCLUDE_CONVERT_H_
...@@ -8,8 +8,9 @@ ...@@ -8,8 +8,9 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef LIBYUV_INCLUDE_FORMAT_CONVERSION_H_
#define LIBYUV_INCLUDE_FORMAT_CONVERSION_H_ #ifndef LIBYUV_INCLUDE_FORMATCONVERSION_H_
#define LIBYUV_INCLUDE_FORMATCONVERSION_H_
#include "basic_types.h" #include "basic_types.h"
...@@ -23,14 +24,18 @@ void BayerRGBToI420(const uint8* src_bayer, int src_pitch_bayer, ...@@ -23,14 +24,18 @@ void BayerRGBToI420(const uint8* src_bayer, int src_pitch_bayer,
uint8* dst_v, int dst_pitch_v, uint8* dst_v, int dst_pitch_v,
int width, int height); int width, int height);
// Converts any 32 bit ARGB to any Bayer RGB format. // Converts any Bayer RGB format to ARGB.
void RGB32ToBayerRGB(const uint8* src_rgb, int src_pitch_rgb, void BayerRGBToARGB(const uint8* src_bayer, int src_pitch_bayer,
uint32 src_fourcc_rgb, uint32 src_fourcc_bayer,
uint8* dst_bayer, int dst_pitch_bayer, uint8* dst_rgb, int dst_pitch_rgb,
uint32 dst_fourcc_bayer, int width, int height);
int width, int height);
// Converts ARGB to any Bayer RGB format.
void ARGBToBayerRGB(const uint8* src_rgb, int src_pitch_rgb,
uint8* dst_bayer, int dst_pitch_bayer,
uint32 dst_fourcc_bayer,
int width, int height);
} // namespace libyuv } // namespace libyuv
#endif // LIBYUV_INCLUDE_FORMAT_CONVERSION_H_ #endif // LIBYUV_INCLUDE_FORMATCONVERSION_H_
...@@ -9,50 +9,128 @@ ...@@ -9,50 +9,128 @@
*/ */
/* #ifndef LIBYUV_INCLUDE_PLANAR_FUNCTIONS_H_
* General operations on YUV images. #define LIBYUV_INCLUDE_PLANAR_FUNCTIONS_H_
*/
#ifndef LIBYUV_INCLUDE_GENERAL_H_
#define LIBYUV_INCLUDE_GENERAL_H_
#include "basic_types.h" #include "basic_types.h"
namespace libyuv { namespace libyuv {
// Supported rotation // Copy I420 to I420.
enum VideoRotationMode void I420Copy(const uint8* src_y, int src_pitch_y,
{ const uint8* src_u, int src_pitch_u,
kRotateNone = 0, const uint8* src_v, int src_pitch_v,
kRotateClockwise = 90, uint8* dst_y, int dst_pitch_y,
kRotateCounterClockwise = -90, uint8* dst_u, int dst_pitch_u,
kRotate180 = 180, uint8* dst_v, int dst_pitch_v,
}; int width, int height);
// I420 mirror // Convert I422 to I420. Used by MJPG.
int void I422ToI420(const uint8* src_y, int src_pitch_y,
I420Mirror(const uint8* src_yplane, int src_ystride, const uint8* src_u, int src_pitch_u,
const uint8* src_uplane, int src_ustride, const uint8* src_v, int src_pitch_v,
const uint8* src_vplane, int src_vstride, uint8* dst_y, int dst_pitch_y,
uint8* dst_yplane, int dst_ystride, uint8* dst_u, int dst_pitch_u,
uint8* dst_uplane, int dst_ustride, uint8* dst_v, int dst_pitch_v,
uint8* dst_vplane, int dst_vstride, int width, int height);
int width, int height);
// Convert M420 to I420.
// Crop/Pad I420 frame to match required dimensions. void M420ToI420(const uint8* src_m420, int src_pitch_m420,
int uint8* dst_y, int dst_pitch_y,
I420CropPad(const uint8* src_frame, int src_width, uint8* dst_u, int dst_pitch_u,
int src_height, uint8* dst_frame, uint8* dst_v, int dst_pitch_v,
int dst_width, int dst_height); int width, int height);
// I420 Crop - make a center cut // Convert Q420 to I420.
int void Q420ToI420(const uint8* src_y, int src_pitch_y,
I420Cut(uint8* frame, const uint8* src_yuy2, int src_pitch_yuy2,
int src_width, int src_height, uint8* dst_y, int dst_pitch_y,
int dst_width, int dst_height); uint8* dst_u, int dst_pitch_u,
uint8* dst_v, int dst_pitch_v,
int width, int height);
} // namespace libyuv
// Convert NV12 to I420. Also used for NV21.
void NV12ToI420(const uint8* src_y,
#endif // LIBYUV_INCLUDE_GENERAL_H_ const uint8* src_uv, int src_pitch,
uint8* dst_y, int dst_pitch_y,
uint8* dst_u, int dst_pitch_u,
uint8* dst_v, int dst_pitch_v,
int width, int height);
// Convert YUY2 to I420.
void YUY2ToI420(const uint8* src_yuy2, int src_pitch_yuy2,
uint8* dst_y, int dst_pitch_y,
uint8* dst_u, int dst_pitch_u,
uint8* dst_v, int dst_pitch_v,
int width, int height);
// Convert UYVY to I420.
void UYVYToI420(const uint8* src_uyvy, int src_pitch_uyvy,
uint8* dst_y, int dst_pitch_y,
uint8* dst_u, int dst_pitch_u,
uint8* dst_v, int dst_pitch_v,
int width, int height);
// Convert I420 to ARGB.
void I420ToARGB(const uint8* src_y, int src_pitch_y,
const uint8* src_u, int src_pitch_u,
const uint8* src_v, int src_pitch_v,
uint8* dst_argb, int dst_pitch_argb,
int width, int height);
// Convert I420 to BGRA.
void I420ToBGRA(const uint8* src_y, int src_pitch_y,
const uint8* src_u, int src_pitch_u,
const uint8* src_v, int src_pitch_v,
uint8* dst_argb, int dst_pitch_argb,
int width, int height);
// Convert I420 to ABGR.
void I420ToABGR(const uint8* src_y, int src_pitch_y,
const uint8* src_u, int src_pitch_u,
const uint8* src_v, int src_pitch_v,
uint8* dst_argb, int dst_pitch_argb,
int width, int height);
// Convert I422 to ARGB.
void I422ToARGB(const uint8* src_y, int src_pitch_y,
const uint8* src_u, int src_pitch_u,
const uint8* src_v, int src_pitch_v,
uint8* dst_argb, int dst_pitch_argb,
int width, int height);
// Convert I444 to ARGB.
void I444ToARGB(const uint8* src_y, int src_pitch_y,
const uint8* src_u, int src_pitch_u,
const uint8* src_v, int src_pitch_v,
uint8* dst_argb, int dst_pitch_argb,
int width, int height);
// Convert I400 to ARGB.
void I400ToARGB(const uint8* src_y, int src_pitch_y,
uint8* dst_argb, int dst_pitch_argb,
int width, int height);
// Convert I400 to ARGB.
void I400ToARGB_Reference(const uint8* src_y, int src_pitch_y,
uint8* dst_argb, int dst_pitch_argb,
int width, int height);
// Convert RAW to ARGB.
void RAWToARGB(const uint8* src_raw, int src_pitch_raw,
uint8* dst_argb, int dst_pitch_argb,
int width, int height);
// Convert BG24 to ARGB.
void BG24ToARGB(const uint8* src_bg24, int src_pitch_bg24,
uint8* dst_argb, int dst_pitch_argb,
int width, int height);
// Convert ABGR to ARGB.
void ABGRToARGB(const uint8* src_abgr, int src_pitch_abgr,
uint8* dst_argb, int dst_pitch_argb,
int width, int height);
} // namespace libyuv
#endif // LIBYUV_INCLUDE_PLANAR_FUNCTIONS_H_
...@@ -16,112 +16,120 @@ ...@@ -16,112 +16,120 @@
namespace libyuv { namespace libyuv {
class PlanarFunctions { // Copy I420 to I420.
public: void I420Copy(const uint8* src_y, int src_pitch_y,
const uint8* src_u, int src_pitch_u,
// Copy I420 to I420. const uint8* src_v, int src_pitch_v,
static void I420Copy(const uint8* src_y, int src_pitch_y, uint8* dst_y, int dst_pitch_y,
const uint8* src_u, int src_pitch_u, uint8* dst_u, int dst_pitch_u,
const uint8* src_v, int src_pitch_v, uint8* dst_v, int dst_pitch_v,
uint8* dst_y, int dst_pitch_y, int width, int height);
uint8* dst_u, int dst_pitch_u,
uint8* dst_v, int dst_pitch_v, // Convert I422 to I420. Used by MJPG.
int width, int height); void I422ToI420(const uint8* src_y, int src_pitch_y,
const uint8* src_u, int src_pitch_u,
// Convert I422 to I420. Used by MJPG. const uint8* src_v, int src_pitch_v,
static void I422ToI420(const uint8* src_y, int src_pitch_y, uint8* dst_y, int dst_pitch_y,
const uint8* src_u, int src_pitch_u, uint8* dst_u, int dst_pitch_u,
const uint8* src_v, int src_pitch_v, uint8* dst_v, int dst_pitch_v,
uint8* dst_y, int dst_pitch_y, int width, int height);
uint8* dst_u, int dst_pitch_u,
uint8* dst_v, int dst_pitch_v, // Convert M420 to I420.
int width, int height); void M420ToI420(const uint8* src_m420, int src_pitch_m420,
uint8* dst_y, int dst_pitch_y,
// Convert M420 to I420. uint8* dst_u, int dst_pitch_u,
static void M420ToI420(const uint8* src_m420, int src_pitch_m420, uint8* dst_v, int dst_pitch_v,
uint8* dst_y, int dst_pitch_y, int width, int height);
uint8* dst_u, int dst_pitch_u,
uint8* dst_v, int dst_pitch_v, // Convert Q420 to I420.
int width, int height); void Q420ToI420(const uint8* src_y, int src_pitch_y,
const uint8* src_yuy2, int src_pitch_yuy2,
// Convert Q420 to I420. uint8* dst_y, int dst_pitch_y,
static void Q420ToI420(const uint8* src_y, int src_pitch_y, uint8* dst_u, int dst_pitch_u,
const uint8* src_yuy2, int src_pitch_yuy2, uint8* dst_v, int dst_pitch_v,
uint8* dst_y, int dst_pitch_y, int width, int height);
uint8* dst_u, int dst_pitch_u,
uint8* dst_v, int dst_pitch_v, // Convert NV12 to I420. Also used for NV21.
int width, int height); void NV12ToI420(const uint8* src_y,
const uint8* src_uv, int src_pitch,
// Convert NV12 to I420. Also used for NV21. uint8* dst_y, int dst_pitch_y,
static void NV12ToI420(const uint8* src_y, uint8* dst_u, int dst_pitch_u,
const uint8* src_uv, int src_pitch, uint8* dst_v, int dst_pitch_v,
uint8* dst_y, int dst_pitch_y, int width, int height);
uint8* dst_u, int dst_pitch_u,
uint8* dst_v, int dst_pitch_v, // Convert YUY2 to I420.
int width, int height); void YUY2ToI420(const uint8* src_yuy2, int src_pitch_yuy2,
uint8* dst_y, int dst_pitch_y,
// Convert YUY2 to I420. uint8* dst_u, int dst_pitch_u,
static void YUY2ToI420(const uint8* src_yuy2, int src_pitch_yuy2, uint8* dst_v, int dst_pitch_v,
uint8* dst_y, int dst_pitch_y, int width, int height);
uint8* dst_u, int dst_pitch_u,
uint8* dst_v, int dst_pitch_v, // Convert UYVY to I420.
int width, int height); void UYVYToI420(const uint8* src_uyvy, int src_pitch_uyvy,
uint8* dst_y, int dst_pitch_y,
// Convert UYVY to I420. uint8* dst_u, int dst_pitch_u,
static void UYVYToI420(const uint8* src_uyvy, int src_pitch_uyvy, uint8* dst_v, int dst_pitch_v,
uint8* dst_y, int dst_pitch_y, int width, int height);
uint8* dst_u, int dst_pitch_u,
uint8* dst_v, int dst_pitch_v, // Convert I420 to ARGB.
int width, int height); void I420ToARGB(const uint8* src_y, int src_pitch_y,
const uint8* src_u, int src_pitch_u,
// Convert I420 to ARGB. const uint8* src_v, int src_pitch_v,
static void I420ToARGB(const uint8* src_y, int src_pitch_y, uint8* dst_argb, int dst_pitch_argb,
const uint8* src_u, int src_pitch_u, int width, int height);
const uint8* src_v, int src_pitch_v,
uint8* dst_argb, int dst_pitch_argb, // Convert I420 to BGRA.
int width, int height); void I420ToBGRA(const uint8* src_y, int src_pitch_y,
const uint8* src_u, int src_pitch_u,
// Convert I422 to ARGB. const uint8* src_v, int src_pitch_v,
static void I422ToARGB(const uint8* src_y, int src_pitch_y, uint8* dst_argb, int dst_pitch_argb,
const uint8* src_u, int src_pitch_u, int width, int height);
const uint8* src_v, int src_pitch_v,
uint8* dst_argb, int dst_pitch_argb, // Convert I420 to ABGR.
int width, int height); void I420ToABGR(const uint8* src_y, int src_pitch_y,
const uint8* src_u, int src_pitch_u,
// Convert I444 to ARGB. const uint8* src_v, int src_pitch_v,
static void I444ToARGB(const uint8* src_y, int src_pitch_y, uint8* dst_argb, int dst_pitch_argb,
const uint8* src_u, int src_pitch_u, int width, int height);
const uint8* src_v, int src_pitch_v,
uint8* dst_argb, int dst_pitch_argb, // Convert I422 to ARGB.
int width, int height); void I422ToARGB(const uint8* src_y, int src_pitch_y,
const uint8* src_u, int src_pitch_u,
// Convert I400 to ARGB. const uint8* src_v, int src_pitch_v,
static void I400ToARGB(const uint8* src_y, int src_pitch_y, uint8* dst_argb, int dst_pitch_argb,
uint8* dst_argb, int dst_pitch_argb, int width, int height);
int width, int height);
// Convert I444 to ARGB.
// Convert I400 to ARGB. void I444ToARGB(const uint8* src_y, int src_pitch_y,
static void I400ToARGB_Reference(const uint8* src_y, int src_pitch_y, const uint8* src_u, int src_pitch_u,
uint8* dst_argb, int dst_pitch_argb, const uint8* src_v, int src_pitch_v,
int width, int height); uint8* dst_argb, int dst_pitch_argb,
int width, int height);
// Convert RAW to ARGB.
static void RAWToARGB(const uint8* src_raw, int src_pitch_raw, // Convert I400 to ARGB.
void I400ToARGB(const uint8* src_y, int src_pitch_y,
uint8* dst_argb, int dst_pitch_argb,
int width, int height);
// Convert I400 to ARGB.
void I400ToARGB_Reference(const uint8* src_y, int src_pitch_y,
uint8* dst_argb, int dst_pitch_argb, uint8* dst_argb, int dst_pitch_argb,
int width, int height); int width, int height);
// Convert BG24 to ARGB. // Convert RAW to ARGB.
static void BG24ToARGB(const uint8* src_bg24, int src_pitch_bg24, void RAWToARGB(const uint8* src_raw, int src_pitch_raw,
uint8* dst_argb, int dst_pitch_argb, uint8* dst_argb, int dst_pitch_argb,
int width, int height); int width, int height);
// Convert ABGR to ARGB. // Convert BG24 to ARGB.
static void ABGRToARGB(const uint8* src_abgr, int src_pitch_abgr, void BG24ToARGB(const uint8* src_bg24, int src_pitch_bg24,
uint8* dst_argb, int dst_pitch_argb, uint8* dst_argb, int dst_pitch_argb,
int width, int height); int width, int height);
DISALLOW_IMPLICIT_CONSTRUCTORS(PlanarFunctions); // Convert ABGR to ARGB.
}; void ABGRToARGB(const uint8* src_abgr, int src_pitch_abgr,
uint8* dst_argb, int dst_pitch_argb,
int width, int height);
} // namespace libyuv } // namespace libyuv
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#ifndef LIBYUV_INCLUDE_SCALE_H_ #ifndef LIBYUV_INCLUDE_SCALE_H_
#define LIBYUV_INCLUDE_SCALE_H_ #define LIBYUV_INCLUDE_SCALE_H_
#include "basic_types.h" #include "basic_types.h"
#if defined(_MSC_VER) #if defined(_MSC_VER)
...@@ -21,43 +20,32 @@ ...@@ -21,43 +20,32 @@
#define ALIGN16(var) var __attribute__((aligned(16))) #define ALIGN16(var) var __attribute__((aligned(16)))
#endif #endif
namespace libyuv {
namespace libyuv
{ // Scales a YUV 4:2:0 image from the input width and height to the
// output width and height. If outh_offset is nonzero, the image is
class YuvScaler { // offset by that many pixels and stretched to (outh - outh_offset * 2)
public: // pixels high, instead of outh.
// Scales a YUV 4:2:0 image from the input width and height to the // If interpolate is not set, a simple nearest-neighbor algorithm is
// output width and height. If outh_offset is nonzero, the image is // used. This produces basic (blocky) quality at the fastest speed.
// offset by that many pixels and stretched to (outh - outh_offset * 2) // If interpolate is set, interpolation is used to produce a better
// pixels high, instead of outh. // quality image, at the expense of speed.
// If interpolate is not set, a simple nearest-neighbor algorithm is // Returns true if successful.
// used. This produces basic (blocky) quality at the fastest speed. bool Scale(const uint8 *in, int32 inw, int32 inh,
// If interpolate is set, interpolation is used to produce a better uint8 *out, int32 outw, int32 outh, int32 outh_offset,
// quality image, at the expense of speed. bool interpolate);
// Returns true if successful.
static bool Scale(const uint8 *in, int32 inw, int32 inh, // Same, but specified in terms of each plane location and stride.
uint8 *out, int32 outw, int32 outh, int32 outh_offset, bool Scale(const uint8 *inY, const uint8 *inU, const uint8 *inV,
bool interpolate); int32 istrideY, int32 istrideU, int32 istrideV,
int32 iwidth, int32 iheight,
// Same, but specified in terms of each plane location and stride. uint8 *outY, uint8 *outU, uint8 *outV,
static bool Scale(const uint8 *inY, const uint8 *inU, const uint8 *inV, int32 ostrideY, int32 ostrideU, int32 ostrideV,
int32 istrideY, int32 istrideU, int32 istrideV, int32 owidth, int32 oheight,
int32 iwidth, int32 iheight, bool interpolate);
uint8 *outY, uint8 *outU, uint8 *outV,
int32 ostrideY, int32 ostrideU, int32 ostrideV, // For testing, allow disabling of optimizations.
int32 owidth, int32 oheight, void SetUseReferenceImpl(bool use);
bool interpolate);
// For testing, allow disabling of optimizations.
static void SetUseReferenceImpl(bool use) { use_reference_impl_ = use; }
private:
static bool use_reference_impl_;
DISALLOW_IMPLICIT_CONSTRUCTORS(YuvScaler);
};
} // namespace libyuv } // namespace libyuv
......
This diff is collapsed.
...@@ -8,9 +8,6 @@ ...@@ -8,9 +8,6 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "format_conversion.h"
#include <assert.h> #include <assert.h>
#include "common.h" #include "common.h"
...@@ -19,6 +16,9 @@ ...@@ -19,6 +16,9 @@
namespace libyuv { namespace libyuv {
// Most code in here is inspired by the material at
// http://www.siliconimaging.com/RGB%20Bayer.htm
enum { enum {
RED = 0, RED = 0,
BLUE = 1, BLUE = 1,
...@@ -274,6 +274,65 @@ static FORCE_INLINE void InterpolateBayerRGBCenter(uint8* r, ...@@ -274,6 +274,65 @@ static FORCE_INLINE void InterpolateBayerRGBCenter(uint8* r,
} }
} }
// Converts any Bayer RGB format to ARGB.
void BayerRGBToARGB(const uint8* src, int src_pitch, uint32 src_fourcc,
uint8* dst, int dst_pitch,
int width, int height) {
assert(width % 2 == 0);
assert(height % 2 == 0);
uint32 colour_map = FourCcToBayerPixelColourMap(src_fourcc);
int src_row_inc = src_pitch * 2 - width;
int dst_row_inc = dst_pitch * 2 - width * 4;
// Iterate over the 2x2 grids.
for (int y1 = 0; y1 < height; y1 += 2) {
for (int x1 = 0; x1 < width; x1 += 2) {
uint32 colours = colour_map;
// Iterate over the four pixels within them.
for (int y2 = 0; y2 < 2; ++y2) {
for (int x2 = 0; x2 < 2; ++x2) {
uint8 r, g, b;
// The low-order byte of the colour map is the current colour.
uint8 current_colour = static_cast<uint8>(colours);
colours >>= 8;
Position pos = GetPosition(x1 + x2, y1 + y2, width, height);
const uint8* src_pixel = &src[y2 * src_pitch + x2];
const uint8* dst_pixel = &dst[y2 * dst_pitch + x2 * 4];
// Convert from Bayer RGB to regular RGB.
if (pos == MIDDLE) {
// 99% of the image is the middle.
InterpolateBayerRGBCenter(&r, &g, &b,
src_pixel, src_pitch,
current_colour);
} else if (pos >= LEFT_EDGE) {
// Next most frequent is edges.
InterpolateBayerRGBEdge(&r, &g, &b,
src_pixel, src_pitch, pos,
current_colour);
} else {
// Last is the corners. There are only 4.
InterpolateBayerRGBCorner(&r, &g, &b,
src_pixel, src_pitch, pos,
current_colour);
}
// Store ARGB
dst[0] = b;
dst[1] = g;
dst[2] = r;
dst[3] = 255u;
}
}
src += 2;
dst += 2 * 4;
}
src += src_row_inc;
dst += dst_row_inc;
}
}
// Converts any Bayer RGB format to I420. // Converts any Bayer RGB format to I420.
void BayerRGBToI420(const uint8* src, int src_pitch, uint32 src_fourcc, void BayerRGBToI420(const uint8* src, int src_pitch, uint32 src_fourcc,
uint8* y, int y_pitch, uint8* y, int y_pitch,
...@@ -430,17 +489,16 @@ static uint32 GenerateSelector(int select0, int select1) { ...@@ -430,17 +489,16 @@ static uint32 GenerateSelector(int select0, int select1) {
static_cast<uint32>((select1 + 12) << 24); static_cast<uint32>((select1 + 12) << 24);
} }
// Converts any 32 bit ARGB to any Bayer RGB format. // Converts 32 bit ARGB to any Bayer RGB format.
void RGB32ToBayerRGB(const uint8* src_rgb, int src_pitch_rgb, void ARGBToBayerRGB(const uint8* src_rgb, int src_pitch_rgb,
uint32 src_fourcc_rgb, uint8* dst_bayer, int dst_pitch_bayer,
uint8* dst_bayer, int dst_pitch_bayer, uint32 dst_fourcc_bayer,
uint32 dst_fourcc_bayer, int width, int height) {
int width, int height) {
assert(width % 2 == 0); assert(width % 2 == 0);
void (*ARGBToBayerRow)(const uint8* src_argb, void (*ARGBToBayerRow)(const uint8* src_argb,
uint8* dst_bayer, uint32 selector, int pix); uint8* dst_bayer, uint32 selector, int pix);
#if defined(HAS_ARGBTOBAYERROW_SSSE3) #if defined(HAS_ARGBTOBAYERROW_SSSE3)
if (CpuInfo::TestCpuFlag(CpuInfo::kCpuHasSSSE3) && if (libyuv::CpuInfo::TestCpuFlag(libyuv::CpuInfo::kCpuHasSSSE3) &&
(width % 4 == 0) && (width % 4 == 0) &&
IS_ALIGNED(src_rgb, 16) && (src_pitch_rgb % 16 == 0) && IS_ALIGNED(src_rgb, 16) && (src_pitch_rgb % 16 == 0) &&
IS_ALIGNED(dst_bayer, 4) && (dst_pitch_bayer % 4 == 0)) { IS_ALIGNED(dst_bayer, 4) && (dst_pitch_bayer % 4 == 0)) {
...@@ -451,7 +509,6 @@ void RGB32ToBayerRGB(const uint8* src_rgb, int src_pitch_rgb, ...@@ -451,7 +509,6 @@ void RGB32ToBayerRGB(const uint8* src_rgb, int src_pitch_rgb,
ARGBToBayerRow = ARGBToBayerRow_C; ARGBToBayerRow = ARGBToBayerRow_C;
} }
assert(src_fourcc_rgb == FOURCC_ARGB);
int blue_index = 0; int blue_index = 0;
int green_index = 1; int green_index = 1;
int red_index = 2; int red_index = 2;
......
This diff is collapsed.
...@@ -14,14 +14,24 @@ ...@@ -14,14 +14,24 @@
#include "basic_types.h" #include "basic_types.h"
extern "C" { extern "C" {
// Can only do 1x.
// This is the second fastest of the scalers.
void FastConvertYUVToRGB32Row(const uint8* y_buf, void FastConvertYUVToRGB32Row(const uint8* y_buf,
const uint8* u_buf, const uint8* u_buf,
const uint8* v_buf, const uint8* v_buf,
uint8* rgb_buf, uint8* rgb_buf,
int width); int width);
void FastConvertYUVToBGRARow(const uint8* y_buf,
const uint8* u_buf,
const uint8* v_buf,
uint8* rgb_buf,
int width);
void FastConvertYUVToABGRRow(const uint8* y_buf,
const uint8* u_buf,
const uint8* v_buf,
uint8* rgb_buf,
int width);
void FastConvertYUV444ToRGB32Row(const uint8* y_buf, void FastConvertYUV444ToRGB32Row(const uint8* y_buf,
const uint8* u_buf, const uint8* u_buf,
const uint8* v_buf, const uint8* v_buf,
...@@ -39,8 +49,12 @@ void FastConvertYToRGB32Row(const uint8* y_buf, ...@@ -39,8 +49,12 @@ void FastConvertYToRGB32Row(const uint8* y_buf,
#endif #endif
#ifdef OSX #ifdef OSX
extern SIMD_ALIGNED(const int16 kCoefficientsRgbY[768][4]); extern SIMD_ALIGNED(const int16 kCoefficientsRgbY[768][4]);
extern SIMD_ALIGNED(const int16 kCoefficientsBgraY[768][4]);
extern SIMD_ALIGNED(const int16 kCoefficientsAbgrY[768][4]);
#else #else
extern SIMD_ALIGNED(const int16 _kCoefficientsRgbY[768][4]); extern SIMD_ALIGNED(const int16 _kCoefficientsRgbY[768][4]);
extern SIMD_ALIGNED(const int16 _kCoefficientsBgraY[768][4]);
extern SIMD_ALIGNED(const int16 _kCoefficientsAbgrY[768][4]);
#endif #endif
// Method to force C version. // Method to force C version.
......
...@@ -55,6 +55,84 @@ void FastConvertYUVToRGB32Row(const uint8* y_buf, // rdi ...@@ -55,6 +55,84 @@ void FastConvertYUVToRGB32Row(const uint8* y_buf, // rdi
); );
} }
void FastConvertYUVToBGRARow(const uint8* y_buf, // rdi
const uint8* u_buf, // rsi
const uint8* v_buf, // rdx
uint8* rgb_buf, // rcx
int width) { // r8
asm(
"1:"
"movzb (%1),%%r10\n"
"lea 1(%1),%1\n"
"movzb (%2),%%r11\n"
"lea 1(%2),%2\n"
"movq 2048(%5,%%r10,8),%%xmm0\n"
"movzb (%0),%%r10\n"
"movq 4096(%5,%%r11,8),%%xmm1\n"
"movzb 0x1(%0),%%r11\n"
"paddsw %%xmm1,%%xmm0\n"
"movq (%5,%%r10,8),%%xmm2\n"
"lea 2(%0),%0\n"
"movq (%5,%%r11,8),%%xmm3\n"
"paddsw %%xmm0,%%xmm2\n"
"paddsw %%xmm0,%%xmm3\n"
"shufps $0x44,%%xmm3,%%xmm2\n"
"psraw $0x6,%%xmm2\n"
"packuswb %%xmm2,%%xmm2\n"
"movq %%xmm2,0x0(%3)\n"
"lea 8(%3),%3\n"
"sub $0x2,%4\n"
"ja 1b\n"
:
: "r"(y_buf), // %0
"r"(u_buf), // %1
"r"(v_buf), // %2
"r"(rgb_buf), // %3
"r"(width), // %4
"r" (_kCoefficientsBgraY) // %5
: "memory", "r10", "r11", "xmm0", "xmm1", "xmm2", "xmm3"
);
}
void FastConvertYUVToABGRRow(const uint8* y_buf, // rdi
const uint8* u_buf, // rsi
const uint8* v_buf, // rdx
uint8* rgb_buf, // rcx
int width) { // r8
asm(
"1:"
"movzb (%1),%%r10\n"
"lea 1(%1),%1\n"
"movzb (%2),%%r11\n"
"lea 1(%2),%2\n"
"movq 2048(%5,%%r10,8),%%xmm0\n"
"movzb (%0),%%r10\n"
"movq 4096(%5,%%r11,8),%%xmm1\n"
"movzb 0x1(%0),%%r11\n"
"paddsw %%xmm1,%%xmm0\n"
"movq (%5,%%r10,8),%%xmm2\n"
"lea 2(%0),%0\n"
"movq (%5,%%r11,8),%%xmm3\n"
"paddsw %%xmm0,%%xmm2\n"
"paddsw %%xmm0,%%xmm3\n"
"shufps $0x44,%%xmm3,%%xmm2\n"
"psraw $0x6,%%xmm2\n"
"packuswb %%xmm2,%%xmm2\n"
"movq %%xmm2,0x0(%3)\n"
"lea 8(%3),%3\n"
"sub $0x2,%4\n"
"ja 1b\n"
:
: "r"(y_buf), // %0
"r"(u_buf), // %1
"r"(v_buf), // %2
"r"(rgb_buf), // %3
"r"(width), // %4
"r" (_kCoefficientsAbgrY) // %5
: "memory", "r10", "r11", "xmm0", "xmm1", "xmm2", "xmm3"
);
}
void FastConvertYUV444ToRGB32Row(const uint8* y_buf, // rdi void FastConvertYUV444ToRGB32Row(const uint8* y_buf, // rdi
const uint8* u_buf, // rsi const uint8* u_buf, // rsi
const uint8* v_buf, // rdx const uint8* v_buf, // rdx
...@@ -166,6 +244,98 @@ void FastConvertYUVToRGB32Row(const uint8* y_buf, ...@@ -166,6 +244,98 @@ void FastConvertYUVToRGB32Row(const uint8* y_buf,
"ret\n" "ret\n"
); );
void FastConvertYUVToBGRARow(const uint8* y_buf,
const uint8* u_buf,
const uint8* v_buf,
uint8* rgb_buf,
int width);
asm(
".text\n"
#if defined(OSX) || defined(IOS)
".globl _FastConvertYUVToBGRARow\n"
"_FastConvertYUVToBGRARow:\n"
#else
".global FastConvertYUVToBGRARow\n"
"FastConvertYUVToBGRARow:\n"
#endif
"pusha\n"
"mov 0x24(%esp),%edx\n"
"mov 0x28(%esp),%edi\n"
"mov 0x2c(%esp),%esi\n"
"mov 0x30(%esp),%ebp\n"
"mov 0x34(%esp),%ecx\n"
"1:"
"movzbl (%edi),%eax\n"
"lea 1(%edi),%edi\n"
"movzbl (%esi),%ebx\n"
"lea 1(%esi),%esi\n"
"movq _kCoefficientsBgraY+2048(,%eax,8),%mm0\n"
"movzbl (%edx),%eax\n"
"paddsw _kCoefficientsBgraY+4096(,%ebx,8),%mm0\n"
"movzbl 0x1(%edx),%ebx\n"
"movq _kCoefficientsBgraY(,%eax,8),%mm1\n"
"lea 2(%edx),%edx\n"
"movq _kCoefficientsBgraY(,%ebx,8),%mm2\n"
"paddsw %mm0,%mm1\n"
"paddsw %mm0,%mm2\n"
"psraw $0x6,%mm1\n"
"psraw $0x6,%mm2\n"
"packuswb %mm2,%mm1\n"
"movntq %mm1,0x0(%ebp)\n"
"lea 8(%ebp),%ebp\n"
"sub $0x2,%ecx\n"
"ja 1b\n"
"popa\n"
"ret\n"
);
void FastConvertYUVToABGRRow(const uint8* y_buf,
const uint8* u_buf,
const uint8* v_buf,
uint8* rgb_buf,
int width);
asm(
".text\n"
#if defined(OSX) || defined(IOS)
".globl _FastConvertYUVToABGRRow\n"
"_FastConvertYUVToABGRRow:\n"
#else
".global FastConvertYUVToABGRRow\n"
"FastConvertYUVToABGRRow:\n"
#endif
"pusha\n"
"mov 0x24(%esp),%edx\n"
"mov 0x28(%esp),%edi\n"
"mov 0x2c(%esp),%esi\n"
"mov 0x30(%esp),%ebp\n"
"mov 0x34(%esp),%ecx\n"
"1:"
"movzbl (%edi),%eax\n"
"lea 1(%edi),%edi\n"
"movzbl (%esi),%ebx\n"
"lea 1(%esi),%esi\n"
"movq _kCoefficientsAbgrY+2048(,%eax,8),%mm0\n"
"movzbl (%edx),%eax\n"
"paddsw _kCoefficientsAbgrY+4096(,%ebx,8),%mm0\n"
"movzbl 0x1(%edx),%ebx\n"
"movq _kCoefficientsAbgrY(,%eax,8),%mm1\n"
"lea 2(%edx),%edx\n"
"movq _kCoefficientsAbgrY(,%ebx,8),%mm2\n"
"paddsw %mm0,%mm1\n"
"paddsw %mm0,%mm2\n"
"psraw $0x6,%mm1\n"
"psraw $0x6,%mm2\n"
"packuswb %mm2,%mm1\n"
"movntq %mm1,0x0(%ebp)\n"
"lea 8(%ebp),%ebp\n"
"sub $0x2,%ecx\n"
"ja 1b\n"
"popa\n"
"ret\n"
);
void FastConvertYUV444ToRGB32Row(const uint8* y_buf, void FastConvertYUV444ToRGB32Row(const uint8* y_buf,
const uint8* u_buf, const uint8* u_buf,
const uint8* v_buf, const uint8* v_buf,
...@@ -250,7 +420,11 @@ void FastConvertYToRGB32Row(const uint8* y_buf, ...@@ -250,7 +420,11 @@ void FastConvertYToRGB32Row(const uint8* y_buf,
static inline void YuvPixel(uint8 y, static inline void YuvPixel(uint8 y,
uint8 u, uint8 u,
uint8 v, uint8 v,
uint8* rgb_buf) { uint8* rgb_buf,
int ashift,
int rshift,
int gshift,
int bshift) {
int b = _kCoefficientsRgbY[256+u][0]; int b = _kCoefficientsRgbY[256+u][0];
int g = _kCoefficientsRgbY[256+u][1]; int g = _kCoefficientsRgbY[256+u][1];
...@@ -272,10 +446,10 @@ static inline void YuvPixel(uint8 y, ...@@ -272,10 +446,10 @@ static inline void YuvPixel(uint8 y,
r >>= 6; r >>= 6;
a >>= 6; a >>= 6;
*reinterpret_cast<uint32*>(rgb_buf) = (packuswb(b)) | *reinterpret_cast<uint32*>(rgb_buf) = (packuswb(b) << bshift) |
(packuswb(g) << 8) | (packuswb(g) << gshift) |
(packuswb(r) << 16) | (packuswb(r) << rshift) |
(packuswb(a) << 24); (packuswb(a) << ashift);
} }
void FastConvertYUVToRGB32Row(const uint8* y_buf, void FastConvertYUVToRGB32Row(const uint8* y_buf,
...@@ -287,10 +461,46 @@ void FastConvertYUVToRGB32Row(const uint8* y_buf, ...@@ -287,10 +461,46 @@ void FastConvertYUVToRGB32Row(const uint8* y_buf,
uint8 u = u_buf[x >> 1]; uint8 u = u_buf[x >> 1];
uint8 v = v_buf[x >> 1]; uint8 v = v_buf[x >> 1];
uint8 y0 = y_buf[x]; uint8 y0 = y_buf[x];
YuvPixel(y0, u, v, rgb_buf); YuvPixel(y0, u, v, rgb_buf, 24, 16, 8, 0);
if ((x + 1) < width) {
uint8 y1 = y_buf[x + 1];
YuvPixel(y1, u, v, rgb_buf + 4, 24, 16, 8, 0);
}
rgb_buf += 8; // Advance 2 pixels.
}
}
void FastConvertYUVToBGRARow(const uint8* y_buf,
const uint8* u_buf,
const uint8* v_buf,
uint8* rgb_buf,
int width) {
for (int x = 0; x < width; x += 2) {
uint8 u = u_buf[x >> 1];
uint8 v = v_buf[x >> 1];
uint8 y0 = y_buf[x];
YuvPixel(y0, u, v, rgb_buf, 0, 8, 16, 24);
if ((x + 1) < width) {
uint8 y1 = y_buf[x + 1];
YuvPixel(y1, u, v, rgb_buf + 4, 0, 8, 16, 24);
}
rgb_buf += 8; // Advance 2 pixels.
}
}
void FastConvertYUVToABGRRow(const uint8* y_buf,
const uint8* u_buf,
const uint8* v_buf,
uint8* rgb_buf,
int width) {
for (int x = 0; x < width; x += 2) {
uint8 u = u_buf[x >> 1];
uint8 v = v_buf[x >> 1];
uint8 y0 = y_buf[x];
YuvPixel(y0, u, v, rgb_buf, 24, 0, 8, 16);
if ((x + 1) < width) { if ((x + 1) < width) {
uint8 y1 = y_buf[x + 1]; uint8 y1 = y_buf[x + 1];
YuvPixel(y1, u, v, rgb_buf + 4); YuvPixel(y1, u, v, rgb_buf + 4, 24, 0, 8, 16);
} }
rgb_buf += 8; // Advance 2 pixels. rgb_buf += 8; // Advance 2 pixels.
} }
......
This diff is collapsed.
...@@ -7,13 +7,8 @@ ...@@ -7,13 +7,8 @@
* in the file PATENTS. All contributing project authors may * in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "row.h"
#define kCoefficientsRgbY _kCoefficientsRgbY + 0 #include "row.h"
#define kCoefficientsRgbU _kCoefficientsRgbY + 2048
#define kCoefficientsRgbV _kCoefficientsRgbY + 4096
extern "C" { extern "C" {
...@@ -25,24 +20,106 @@ void FastConvertYUVToRGB32Row(const uint8* y_buf, ...@@ -25,24 +20,106 @@ void FastConvertYUVToRGB32Row(const uint8* y_buf,
int width) { int width) {
__asm { __asm {
pushad pushad
mov edx, [esp + 32 + 4] // Y mov edx, [esp + 32 + 4]
mov edi, [esp + 32 + 8] // U mov edi, [esp + 32 + 8]
mov esi, [esp + 32 + 12] // V mov esi, [esp + 32 + 12]
mov ebp, [esp + 32 + 16] // rgb mov ebp, [esp + 32 + 16]
mov ecx, [esp + 32 + 20] // width mov ecx, [esp + 32 + 20]
convertloop :
movzx eax, byte ptr [edi]
lea edi, [edi + 1]
movzx ebx, byte ptr [esi]
lea esi, [esi + 1]
movq mm0, [_kCoefficientsRgbY + 2048 + 8 * eax]
movzx eax, byte ptr [edx]
paddsw mm0, [_kCoefficientsRgbY + 4096 + 8 * ebx]
movzx ebx, byte ptr [edx + 1]
movq mm1, [_kCoefficientsRgbY + 8 * eax]
lea edx, [edx + 2]
movq mm2, [_kCoefficientsRgbY + 8 * ebx]
paddsw mm1, mm0
paddsw mm2, mm0
psraw mm1, 6
psraw mm2, 6
packuswb mm1, mm2
movntq [ebp], mm1
lea ebp, [ebp + 8]
sub ecx, 2
ja convertloop
popad
ret
}
}
__declspec(naked)
void FastConvertYUVToBGRARow(const uint8* y_buf,
const uint8* u_buf,
const uint8* v_buf,
uint8* rgb_buf,
int width) {
__asm {
pushad
mov edx, [esp + 32 + 4]
mov edi, [esp + 32 + 8]
mov esi, [esp + 32 + 12]
mov ebp, [esp + 32 + 16]
mov ecx, [esp + 32 + 20]
convertloop :
movzx eax, byte ptr [edi]
lea edi, [edi + 1]
movzx ebx, byte ptr [esi]
lea esi, [esi + 1]
movq mm0, [_kCoefficientsBgraY + 2048 + 8 * eax]
movzx eax, byte ptr [edx]
paddsw mm0, [_kCoefficientsBgraY + 4096 + 8 * ebx]
movzx ebx, byte ptr [edx + 1]
movq mm1, [_kCoefficientsBgraY + 8 * eax]
lea edx, [edx + 2]
movq mm2, [_kCoefficientsBgraY + 8 * ebx]
paddsw mm1, mm0
paddsw mm2, mm0
psraw mm1, 6
psraw mm2, 6
packuswb mm1, mm2
movntq [ebp], mm1
lea ebp, [ebp + 8]
sub ecx, 2
ja convertloop
popad
ret
}
}
__declspec(naked)
void FastConvertYUVToABGRRow(const uint8* y_buf,
const uint8* u_buf,
const uint8* v_buf,
uint8* rgb_buf,
int width) {
__asm {
pushad
mov edx, [esp + 32 + 4]
mov edi, [esp + 32 + 8]
mov esi, [esp + 32 + 12]
mov ebp, [esp + 32 + 16]
mov ecx, [esp + 32 + 20]
convertloop : convertloop :
movzx eax, byte ptr [edi] movzx eax, byte ptr [edi]
lea edi, [edi + 1] lea edi, [edi + 1]
movzx ebx, byte ptr [esi] movzx ebx, byte ptr [esi]
lea esi, [esi + 1] lea esi, [esi + 1]
movq mm0, [kCoefficientsRgbU + 8 * eax] movq mm0, [_kCoefficientsAbgrY + 2048 + 8 * eax]
movzx eax, byte ptr [edx] movzx eax, byte ptr [edx]
paddsw mm0, [kCoefficientsRgbV + 8 * ebx] paddsw mm0, [_kCoefficientsAbgrY + 4096 + 8 * ebx]
movzx ebx, byte ptr [edx + 1] movzx ebx, byte ptr [edx + 1]
movq mm1, [kCoefficientsRgbY + 8 * eax] movq mm1, [_kCoefficientsAbgrY + 8 * eax]
lea edx, [edx + 2] lea edx, [edx + 2]
movq mm2, [kCoefficientsRgbY + 8 * ebx] movq mm2, [_kCoefficientsAbgrY + 8 * ebx]
paddsw mm1, mm0 paddsw mm1, mm0
paddsw mm2, mm0 paddsw mm2, mm0
psraw mm1, 6 psraw mm1, 6
...@@ -77,11 +154,11 @@ void FastConvertYUV444ToRGB32Row(const uint8* y_buf, ...@@ -77,11 +154,11 @@ void FastConvertYUV444ToRGB32Row(const uint8* y_buf,
lea edi, [edi + 1] lea edi, [edi + 1]
movzx ebx, byte ptr [esi] movzx ebx, byte ptr [esi]
lea esi, [esi + 1] lea esi, [esi + 1]
movq mm0, [kCoefficientsRgbU + 8 * eax] movq mm0, [_kCoefficientsRgbY + 2048 + 8 * eax]
movzx eax, byte ptr [edx] movzx eax, byte ptr [edx]
paddsw mm0, [kCoefficientsRgbV + 8 * ebx] paddsw mm0, [_kCoefficientsRgbY + 4096 + 8 * ebx]
lea edx, [edx + 1] lea edx, [edx + 1]
paddsw mm0, [kCoefficientsRgbY + 8 * eax] paddsw mm0, [_kCoefficientsRgbY + 8 * eax]
psraw mm0, 6 psraw mm0, 6
packuswb mm0, mm0 packuswb mm0, mm0
movd [ebp], mm0 movd [ebp], mm0
...@@ -106,10 +183,10 @@ void FastConvertYToRGB32Row(const uint8* y_buf, ...@@ -106,10 +183,10 @@ void FastConvertYToRGB32Row(const uint8* y_buf,
convertloop : convertloop :
movzx ebx, byte ptr [eax] movzx ebx, byte ptr [eax]
movq mm0, [kCoefficientsRgbY + 8 * ebx] movq mm0, [_kCoefficientsRgbY + 8 * ebx]
psraw mm0, 6 psraw mm0, 6
movzx ebx, byte ptr [eax + 1] movzx ebx, byte ptr [eax + 1]
movq mm1, [kCoefficientsRgbY + 8 * ebx] movq mm1, [_kCoefficientsRgbY + 8 * ebx]
psraw mm1, 6 psraw mm1, 6
packuswb mm0, mm1 packuswb mm0, mm1
lea eax, [eax + 2] lea eax, [eax + 2]
......
...@@ -46,8 +46,12 @@ namespace libyuv { ...@@ -46,8 +46,12 @@ namespace libyuv {
// NOT the optimized versions. Useful for debugging and // NOT the optimized versions. Useful for debugging and
// when comparing the quality of the resulting YUV planes // when comparing the quality of the resulting YUV planes
// as produced by the optimized and non-optimized versions. // as produced by the optimized and non-optimized versions.
bool YuvScaler::use_reference_impl_ = false;
bool use_reference_impl_ = false;
void SetUseReferenceImpl(bool use) {
use_reference_impl_ = use;
}
/** /**
* NEON downscalers with interpolation. * NEON downscalers with interpolation.
...@@ -2790,13 +2794,13 @@ static void ScalePlane(const uint8 *in, int32 istride, ...@@ -2790,13 +2794,13 @@ static void ScalePlane(const uint8 *in, int32 istride,
* suitable for handling the desired resolutions. * suitable for handling the desired resolutions.
* *
*/ */
bool YuvScaler::Scale(const uint8 *inY, const uint8 *inU, const uint8 *inV, bool Scale(const uint8 *inY, const uint8 *inU, const uint8 *inV,
int32 istrideY, int32 istrideU, int32 istrideV, int32 istrideY, int32 istrideU, int32 istrideV,
int32 iwidth, int32 iheight, int32 iwidth, int32 iheight,
uint8 *outY, uint8 *outU, uint8 *outV, uint8 *outY, uint8 *outU, uint8 *outV,
int32 ostrideY, int32 ostrideU, int32 ostrideV, int32 ostrideY, int32 ostrideU, int32 ostrideV,
int32 owidth, int32 oheight, int32 owidth, int32 oheight,
bool interpolate) { bool interpolate) {
if (!inY || !inU || !inV || iwidth <= 0 || iheight <= 0 || if (!inY || !inU || !inV || iwidth <= 0 || iheight <= 0 ||
!outY || !outU || !outV || owidth <= 0 || oheight <= 0) { !outY || !outU || !outV || owidth <= 0 || oheight <= 0) {
return false; return false;
...@@ -2818,9 +2822,9 @@ bool YuvScaler::Scale(const uint8 *inY, const uint8 *inU, const uint8 *inV, ...@@ -2818,9 +2822,9 @@ bool YuvScaler::Scale(const uint8 *inY, const uint8 *inU, const uint8 *inV,
return true; return true;
} }
bool YuvScaler::Scale(const uint8 *in, int32 iwidth, int32 iheight, bool Scale(const uint8 *in, int32 iwidth, int32 iheight,
uint8 *out, int32 owidth, int32 oheight, int32 ooffset, uint8 *out, int32 owidth, int32 oheight, int32 ooffset,
bool interpolate) { bool interpolate) {
if (!in || iwidth <= 0 || iheight <= 0 || if (!in || iwidth <= 0 || iheight <= 0 ||
!out || owidth <= 0 || oheight <= 0 || ooffset < 0 || !out || owidth <= 0 || oheight <= 0 || ooffset < 0 ||
ooffset >= oheight) { ooffset >= oheight) {
......
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