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
......
...@@ -37,11 +37,11 @@ void *memcpy_8(void * dest, const void * src, size_t n); ...@@ -37,11 +37,11 @@ void *memcpy_8(void * dest, const void * src, size_t n);
int int
Convert::I420ToRGB24(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)
{ {
if (src_yplane == NULL || src_uplane == NULL || src_vplane == NULL || if (src_yplane == NULL || src_uplane == NULL || src_vplane == NULL ||
dst_frame == NULL) dst_frame == NULL)
...@@ -106,168 +106,13 @@ Convert::I420ToRGB24(const uint8* src_yplane, int src_ystride, ...@@ -106,168 +106,13 @@ Convert::I420ToRGB24(const uint8* src_yplane, int src_ystride,
return 0; return 0;
} }
int
Convert::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)
{
if (src_yplane == NULL || src_uplane == NULL || src_vplane == NULL ||
dst_frame == NULL){
return -1;
}
uint8* out1 = dst_frame;
uint8* out2 = out1 + dst_stride * 4;
const uint8 *y1,*y2, *u, *v;
y1 = src_yplane;
y2 = src_yplane + src_ystride;
u = src_uplane;
v = src_vplane;
int h, w;
int tmpR, tmpG, tmpB;
for (h = ((src_height + 1) >> 1); h > 0; h--){
// Do 2 rows at the time
for (w = 0; w < ((src_width + 1) >> 1); w++){
// Vertical and horizontal sub-sampling
tmpR = (int32)((mapYc[y1[0]] + mapVcr[v[0]] + 128) >> 8);
tmpG = (int32)((mapYc[y1[0]] + mapUcg[u[0]] + mapVcg[v[0]] + 128) >> 8);
tmpB = (int32)((mapYc[y1[0]] + mapUcb[u[0]] + 128) >> 8);
out1[0] = Clip(tmpB);
out1[1] = Clip(tmpG);
out1[2] = Clip(tmpR);
out1[3] = 0xff;
tmpR = (int32)((mapYc[y1[1]] + mapVcr[v[0]] + 128) >> 8);
tmpG = (int32)((mapYc[y1[1]] + mapUcg[u[0]] + mapVcg[v[0]] + 128) >> 8);
tmpB = (int32)((mapYc[y1[1]] + mapUcb[u[0]] + 128) >> 8);
out1[4] = Clip(tmpB);
out1[5] = Clip(tmpG);
out1[6] = Clip(tmpR);
out1[7] = 0xff;
tmpR = (int32)((mapYc[y2[0]] + mapVcr[v[0]] + 128) >> 8);
tmpG = (int32)((mapYc[y2[0]] + mapUcg[u[0]] + mapVcg[v[0]] + 128) >> 8);
tmpB = (int32)((mapYc[y2[0]] + mapUcb[u[0]] + 128) >> 8);
out2[0] = Clip(tmpB);
out2[1] = Clip(tmpG);
out2[2] = Clip(tmpR);
out2[3] = 0xff;
tmpR = (int32)((mapYc[y2[1]] + mapVcr[v[0]] + 128) >> 8);
tmpG = (int32)((mapYc[y2[1]] + mapUcg[u[0]] + mapVcg[v[0]] + 128) >> 8);
tmpB = (int32)((mapYc[y2[1]] + mapUcb[u[0]] + 128) >> 8);
out2[4] = Clip(tmpB);
out2[5] = Clip(tmpG);
out2[6] = Clip(tmpR);
out2[7] = 0xff;
out1 += 8;
out2 += 8;
y1 += 2;
y2 += 2;
u++;
v++;
}
y1 += 2 * src_ystride - src_width;
y2 += 2 * src_ystride - src_width;
u += src_ustride - ((src_width + 1) >> 1);
v += src_vstride - ((src_width + 1) >> 1);
out1 += (2 * dst_stride - src_width) * 4;
out2 += (2 * dst_stride - src_width) * 4;
} // end height for
return 0;
}
int
Convert::I420ToBGRA(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)
{
if (src_yplane == NULL || src_uplane == NULL || src_vplane == NULL ||
dst_frame == NULL){
return -1;
}
uint8* out1 = dst_frame;
uint8* out2 = out1 + dst_stride * 4;
const uint8 *y1,*y2, *u, *v;
y1 = src_yplane;
y2 = src_yplane + src_ystride;
u = src_uplane;
v = src_vplane;
int h, w;
int tmpR, tmpG, tmpB;
for (h = ((src_height + 1) >> 1); h > 0; h--){
// Do 2 rows at the time
for (w = 0; w < ((src_width + 1) >> 1); w++){
// Vertical and horizontal sub-sampling
tmpR = (int32)((mapYc[y1[0]] + mapVcr[v[0]] + 128) >> 8);
tmpG = (int32)((mapYc[y1[0]] + mapUcg[u[0]] + mapVcg[v[0]] + 128) >> 8);
tmpB = (int32)((mapYc[y1[0]] + mapUcb[u[0]] + 128) >> 8);
out1[0] = 0xff;
out1[1] = Clip(tmpR);
out1[2] = Clip(tmpG);
out1[3] = Clip(tmpB);
tmpR = (int32)((mapYc[y1[1]] + mapVcr[v[0]] + 128) >> 8);
tmpG = (int32)((mapYc[y1[1]] + mapUcg[u[0]] + mapVcg[v[0]] + 128) >> 8);
tmpB = (int32)((mapYc[y1[1]] + mapUcb[u[0]] + 128) >> 8);
out1[4] = 0xff;
out1[5] = Clip(tmpR);
out1[6] = Clip(tmpG);
out1[7] = Clip(tmpB);
tmpR = (int32)((mapYc[y2[0]] + mapVcr[v[0]] + 128) >> 8);
tmpG = (int32)((mapYc[y2[0]] + mapUcg[u[0]] + mapVcg[v[0]] + 128) >> 8);
tmpB = (int32)((mapYc[y2[0]] + mapUcb[u[0]] + 128) >> 8);
out2[0] = 0xff;
out2[1] = Clip(tmpR);
out2[2] = Clip(tmpG);
out2[3] = Clip(tmpB);
tmpR = (int32)((mapYc[y2[1]] + mapVcr[v[0]] + 128) >> 8);
tmpG = (int32)((mapYc[y2[1]] + mapUcg[u[0]] + mapVcg[v[0]] + 128) >> 8);
tmpB = (int32)((mapYc[y2[1]] + mapUcb[u[0]] + 128) >> 8);
out2[4] = 0xff;
out2[5] = Clip(tmpR);
out2[6] = Clip(tmpG);
out2[7] = Clip(tmpB);
out1 += 8;
out2 += 8;
y1 += 2;
y2 += 2;
u++;
v++;
}
y1 += 2 * src_ystride - src_width;
y2 += 2 * src_ystride - src_width;
u += src_ustride - ((src_width + 1) >> 1);
v += src_vstride - ((src_width + 1) >> 1);
out1 += (2 * dst_stride - src_width) * 4;
out2 += (2 * dst_stride - src_width) * 4;
} // end height for
return 0;
}
// Little Endian... // Little Endian...
int int
Convert::I420ToARGB4444(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)
{ {
if (src_yplane == NULL || src_uplane == NULL || src_vplane == NULL || if (src_yplane == NULL || src_uplane == NULL || src_vplane == NULL ||
dst_frame == NULL){ dst_frame == NULL){
...@@ -332,11 +177,11 @@ Convert::I420ToARGB4444(const uint8* src_yplane, int src_ystride, ...@@ -332,11 +177,11 @@ Convert::I420ToARGB4444(const uint8* src_yplane, int src_ystride,
int int
Convert::I420ToRGB565(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_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)
{ {
if (src_yplane == NULL || src_uplane == NULL || src_vplane == NULL || if (src_yplane == NULL || src_uplane == NULL || src_vplane == NULL ||
dst_frame == NULL){ dst_frame == NULL){
...@@ -414,11 +259,11 @@ Convert::I420ToRGB565(const uint8* src_yplane, int src_ystride, ...@@ -414,11 +259,11 @@ Convert::I420ToRGB565(const uint8* src_yplane, int src_ystride,
int int
Convert::I420ToARGB1555(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)
{ {
if (src_yplane == NULL || src_uplane == NULL || src_vplane == NULL || if (src_yplane == NULL || src_uplane == NULL || src_vplane == NULL ||
dst_frame == NULL){ dst_frame == NULL){
...@@ -485,11 +330,11 @@ Convert::I420ToARGB1555(const uint8* src_yplane, int src_ystride, ...@@ -485,11 +330,11 @@ Convert::I420ToARGB1555(const uint8* src_yplane, int src_ystride,
int int
Convert::I420ToYUY2(const uint8* src_yplane, int src_ystride, 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)
{ {
if (src_yplane == NULL || src_uplane == NULL || src_vplane == NULL || if (src_yplane == NULL || src_uplane == NULL || src_vplane == NULL ||
dst_frame == NULL){ dst_frame == NULL){
...@@ -601,11 +446,11 @@ Convert::I420ToYUY2(const uint8* src_yplane, int src_ystride, ...@@ -601,11 +446,11 @@ Convert::I420ToYUY2(const uint8* src_yplane, int src_ystride,
} }
int int
Convert::I420ToUYVY(const uint8* src_yplane, int src_ystride, I420ToUYVY(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)
{ {
if (src_yplane == NULL || src_uplane == NULL || src_vplane == NULL || if (src_yplane == NULL || src_uplane == NULL || src_vplane == NULL ||
dst_frame == NULL){ dst_frame == NULL){
...@@ -717,10 +562,10 @@ loop0: ...@@ -717,10 +562,10 @@ loop0:
int int
Convert::NV12ToRGB565(const uint8* src_yplane, int src_ystride, NV12ToRGB565(const uint8* src_yplane, int src_ystride,
const uint8* src_uvplane, int src_uvstride, 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)
{ {
if (src_yplane == NULL || src_uvplane == NULL || dst_frame == NULL){ if (src_yplane == NULL || src_uvplane == NULL || dst_frame == NULL){
return -1; return -1;
...@@ -788,11 +633,11 @@ Convert::NV12ToRGB565(const uint8* src_yplane, int src_ystride, ...@@ -788,11 +633,11 @@ Convert::NV12ToRGB565(const uint8* src_yplane, int src_ystride,
} }
int int
Convert::I420ToABGR(const uint8* src_yplane, int src_ystride, I420ToABGR(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)
{ {
if (src_yplane == NULL || src_uplane == NULL || src_vplane == NULL || if (src_yplane == NULL || src_uplane == NULL || src_vplane == NULL ||
dst_frame == NULL){ dst_frame == NULL){
...@@ -872,56 +717,10 @@ Convert::I420ToABGR(const uint8* src_yplane, int src_ystride, ...@@ -872,56 +717,10 @@ Convert::I420ToABGR(const uint8* src_yplane, int src_ystride,
return 0; return 0;
} }
int
Convert::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)
{
if (dst_yplane == NULL || dst_uplane == NULL || dst_vplane == NULL ||
src_frame == NULL){
return -1;
}
int i, j;
uint8* outI = dst_yplane;
uint8* outU = dst_uplane;
uint8* outV = dst_vplane;
// U0Y0V0Y1..U2Y2V2Y3.....
for (i = 0; i < ((src_height + 1) >> 1); i++){
for (j = 0; j < ((src_width + 1) >> 1); j++){
outI[0] = src_frame[1];
*outU = src_frame[0];
outI[1] = src_frame[3];
*outV = src_frame[2];
src_frame += 4;
outI += 2;
outU++;
outV++;
}
for (j = 0; j < ((src_width + 1) >> 1); j++)
{
outI[0] = src_frame[1];
outI[1] = src_frame[3];
src_frame += 4;
outI += 2;
}
outI += dst_ystride - src_width;
outU += dst_ustride - ((src_width + 1) << 1);
outV += dst_vstride - ((src_width + 1) << 1);
}
return 0;
}
int int
Convert::RGB24ToARGB(const uint8* src_frame, int src_stride, RGB24ToARGB(const uint8* src_frame, int src_stride,
uint8* dst_frame, int dst_stride, uint8* dst_frame, int dst_stride,
int src_width, int src_height) int src_width, int src_height)
{ {
if (src_frame == NULL || dst_frame == NULL){ if (src_frame == NULL || dst_frame == NULL){
return -1; return -1;
...@@ -936,7 +735,7 @@ Convert::RGB24ToARGB(const uint8* src_frame, int src_stride, ...@@ -936,7 +735,7 @@ Convert::RGB24ToARGB(const uint8* src_frame, int src_stride,
{ {
for (j = 0; j < src_width; j++) for (j = 0; j < src_width; j++)
{ {
offset = j*4; offset = j * 4;
outFrame[0 + offset] = inFrame[0]; outFrame[0 + offset] = inFrame[0];
outFrame[1 + offset] = inFrame[1]; outFrame[1 + offset] = inFrame[1];
outFrame[2 + offset] = inFrame[2]; outFrame[2 + offset] = inFrame[2];
...@@ -949,324 +748,188 @@ Convert::RGB24ToARGB(const uint8* src_frame, int src_stride, ...@@ -949,324 +748,188 @@ Convert::RGB24ToARGB(const uint8* src_frame, int src_stride,
return 0; return 0;
} }
// ARGBToI420Row_C etc row functions use the following macro, generating
// code with RGB offsets/strides different for each version. Less error
// prone than duplicating the code.
// template could be used, but macro method works for C and asm and this is
// performance critical code.
#define MAKEROWRGBTOI420(NAME,R,G,B,BPP) \
static void \
NAME(const uint8* src_row0, const uint8* src_row1, \
uint8* dst_yplane0, uint8* dst_yplane1, \
uint8* dst_uplane, \
uint8* dst_vplane, \
int src_width) { \
for (int x = 0; x < src_width - 1; x += 2) { \
dst_yplane0[0] = (uint8)((src_row0[R] * 66 + \
src_row0[G] * 129 + \
src_row0[B] * 25 + 128) >> 8) + 16; \
dst_yplane0[1] = (uint8)((src_row0[R + BPP] * 66 + \
src_row0[G + BPP] * 129 + \
src_row0[B + BPP] * 25 + 128) >> 8) + 16; \
dst_yplane1[0] = (uint8)((src_row1[R] * 66 + \
src_row1[G] * 129 + \
src_row1[B] * 25 + 128) >> 8) + 16; \
dst_yplane1[1] = (uint8)((src_row1[R + BPP] * 66 + \
src_row1[G + BPP] * 129 + \
src_row1[B + BPP] * 25 + 128) >> 8) + 16; \
dst_uplane[0] = (uint8)(((src_row0[R] + src_row0[R + BPP] + \
src_row1[R] + src_row1[R + BPP]) * -38 + \
(src_row0[G] + src_row0[G + BPP] + \
src_row1[G] + src_row1[G + BPP]) * -74 + \
(src_row0[B] + src_row0[B + BPP] + \
src_row1[B] + src_row1[B + BPP]) * 112 + \
+ 512) >> 10) + 128; \
dst_vplane[0] = (uint8)(((src_row0[R] + src_row0[R + BPP] + \
src_row1[R] + src_row1[R + BPP]) * 112 + \
(src_row0[G] + src_row0[G + BPP] + \
src_row1[G] + src_row1[G + BPP]) * -94 + \
(src_row0[B] + src_row0[B + BPP] + \
src_row1[B] + src_row1[B + BPP]) * -18 + \
+ 512) >> 10) + 128; \
dst_yplane0 += 2; \
dst_yplane1 += 2; \
++dst_uplane; \
++dst_vplane; \
src_row0 += BPP * 2; \
src_row1 += BPP * 2; \
} \
if (src_width & 1) { \
dst_yplane0[0] = (uint8)((src_row0[R] * 66 + \
src_row0[G] * 129 + \
src_row0[B] * 25 + 128) >> 8) + 16; \
dst_yplane1[0] = (uint8)((src_row1[R] * 66 + \
src_row1[G] * 129 + \
src_row1[B] * 25 + 128) >> 8) + 16; \
dst_uplane[0] = (uint8)(((src_row0[R] + \
src_row1[R]) * -38 + \
(src_row0[G] + \
src_row1[G]) * -74 + \
(src_row0[B] + \
src_row1[B]) * 112 + \
+ 256) >> 9) + 128; \
dst_vplane[0] = (uint8)(((src_row0[R] + \
src_row1[R]) * 112 + \
(src_row0[G] + \
src_row1[G]) * -94 + \
(src_row0[B] + \
src_row1[B]) * -18 + \
+ 256) >> 9) + 128; \
} \
}
int // Generate variations of RGBToI420. Parameters are r,g,b offsets within a
Convert::RGB24ToI420(const uint8* src_frame, int src_stride, // pixel, and number of bytes per pixel.
MAKEROWRGBTOI420(ARGBToI420Row_C, 2, 1, 0, 4)
MAKEROWRGBTOI420(BGRAToI420Row_C, 1, 2, 3, 4)
MAKEROWRGBTOI420(ABGRToI420Row_C, 0, 1, 2, 4)
MAKEROWRGBTOI420(RGB24ToI420Row_C, 2, 1, 0, 3)
MAKEROWRGBTOI420(RAWToI420Row_C, 0, 1, 2, 3)
static int RGBToI420(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,
{ void (*RGBToI420Row)(const uint8* src_row0,
const uint8* src_row1,
uint8* dst_yplane0,
uint8* dst_yplane1,
uint8* dst_uplane,
uint8* dst_vplane,
int src_width)) {
if (src_frame == NULL || dst_yplane == NULL || if (src_frame == NULL || dst_yplane == NULL ||
dst_vplane == NULL || dst_vplane == NULL) dst_vplane == NULL || dst_vplane == NULL) {
return -1; return -1;
}
uint8* yStartPtr; if (src_height < 0) {
uint8* yStartPtr2; src_height = -src_height;
uint8* uStartPtr; src_frame = src_frame + src_stride * (src_height -1);
uint8* vStartPtr; src_stride = -src_stride;
const uint8* inpPtr; }
const uint8* inpPtr2; for (int y = 0; y < src_height - 1; y += 2) {
int h, w; RGBToI420Row(src_frame, src_frame + src_stride,
dst_yplane, dst_yplane + dst_ystride,
yStartPtr = dst_yplane; dst_uplane, dst_vplane,
yStartPtr2 = yStartPtr + dst_ystride; src_width);
uStartPtr = dst_uplane; src_frame += src_stride * 2;
vStartPtr = dst_vplane; dst_yplane += dst_ystride * 2;
inpPtr = src_frame + src_stride * src_height * 3 - 3 * src_height; dst_uplane += dst_ustride;
inpPtr2 = inpPtr - 3 * src_stride; dst_vplane += dst_vstride;
}
for (h = 0; h < ((src_height + 1) >> 1); h++ ){ if (src_height & 1) {
for (w = 0; w < ((src_width + 1) >> 1); w++){ RGBToI420Row(src_frame, src_frame,
// Y dst_yplane, dst_yplane,
yStartPtr[0] = (uint8)((66 * inpPtr[2] + 129 * inpPtr[1] dst_uplane, dst_vplane,
+ 25 * inpPtr[0] + 128) >> 8) + 16; src_width);
yStartPtr2[0] = (uint8)((66 * inpPtr2[2] + 129 * inpPtr2[1] }
+ 25 * inpPtr2[0] + 128) >> 8) + 16;
// Moving to next column
yStartPtr[1] = (uint8)((66 * inpPtr[5] + 129 * inpPtr[4]
+ 25 * inpPtr[3] + 128) >> 8) + 16;
yStartPtr2[1] = (uint8)((66 * inpPtr2[5] + 129 * inpPtr2[4]
+ 25 * inpPtr2[3] + 128) >> 8 ) + 16;
// U
uStartPtr[0] = (uint8)((-38 * inpPtr[2] - 74 * inpPtr[1] +
112 * inpPtr[0] + 128) >> 8) + 128;
// V
vStartPtr[0] = (uint8)((112 * inpPtr[2] -94 * inpPtr[1] -
18 * inpPtr[0] + 128) >> 8) + 128;
yStartPtr += 2;
yStartPtr2 += 2;
uStartPtr++;
vStartPtr++;
inpPtr += 6;
inpPtr2 += 6;
} // end for w
yStartPtr += dst_ystride + dst_ystride - src_width;
yStartPtr2 += dst_ystride + dst_ystride - src_width;
uStartPtr += dst_ustride + dst_ustride - ((src_width + 1) >> 1);
vStartPtr += dst_vstride + dst_vstride - ((src_width + 1) >> 1);
inpPtr -= 3 * (2 * src_stride + src_width);
inpPtr2 -= 3 * (2 * src_stride + src_width);
} // end for h
return 0; return 0;
} }
int int
Convert::RAWToI420(const uint8* src_frame, int src_stride, ARGBToI420(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) {
{ return RGBToI420(src_frame, src_stride,
if (src_frame == NULL || dst_yplane == NULL || dst_yplane, dst_ystride,
dst_vplane == NULL || dst_vplane == NULL) dst_uplane, dst_ustride,
return -1; dst_vplane, dst_vstride,
src_width, src_height, ARGBToI420Row_C);
uint8* yStartPtr;
uint8* yStartPtr2;
uint8* uStartPtr;
uint8* vStartPtr;
const uint8* inpPtr;
const uint8* inpPtr2;
int h, w;
yStartPtr = dst_yplane;
yStartPtr2 = yStartPtr + dst_ystride;
uStartPtr = dst_uplane;
vStartPtr = dst_vplane;
inpPtr = src_frame + src_stride * src_height * 3 - 3 * src_height;
inpPtr2 = inpPtr - 3 * src_stride;
// Same as RGB24 - reverse ordering
for (h = 0; h < ((src_height + 1) >> 1); h++){
for (w = 0; w < ((src_width + 1) >> 1); w++){
// Y
yStartPtr[0] = (uint8)((66 * inpPtr[0] + 129 * inpPtr[1]
+ 25 * inpPtr[2] + 128) >> 8) + 16;
yStartPtr2[0] = (uint8)((66 * inpPtr2[2] + 129 * inpPtr2[1]
+ 25 * inpPtr2[0] + 128) >> 8) + 16;
// Moving to next column
yStartPtr[1] = (uint8)((66 * inpPtr[3] + 129 * inpPtr[4]
+ 25 * inpPtr[5] + 128) >> 8) + 16;
yStartPtr2[1] = (uint8)((66 * inpPtr2[3] + 129 * inpPtr2[4]
+ 25 * inpPtr2[5] + 128) >> 8 ) + 16;
// U
uStartPtr[0] = (uint8)((-38 * inpPtr[0] - 74 * inpPtr[1] +
112 * inpPtr[2] + 128) >> 8) + 128;
// V
vStartPtr[0] = (uint8)((112 * inpPtr[0] -94 * inpPtr[1] -
18 * inpPtr[2] + 128) >> 8) + 128;
yStartPtr += 2;
yStartPtr2 += 2;
uStartPtr++;
vStartPtr++;
inpPtr += 6;
inpPtr2 += 6;
} // end for w
yStartPtr += dst_ystride + dst_ystride - src_width;
yStartPtr2 += dst_ystride + dst_ystride - src_width;
uStartPtr += dst_ustride + dst_ustride - ((src_width + 1) >> 1);
vStartPtr += dst_vstride + dst_vstride - ((src_width + 1) >> 1);
inpPtr -= 3 * (2 * src_stride + src_width);
inpPtr2 -= 3 * (2 * src_stride + src_width);
} // end for h
return 0;
} }
int int
Convert::BGRAToI420(const uint8* src_frame, int src_stride, BGRAToI420(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) {
{ return RGBToI420(src_frame, src_stride,
if (src_frame == NULL || dst_yplane == NULL || dst_yplane, dst_ystride,
dst_vplane == NULL || dst_vplane == NULL) dst_uplane, dst_ustride,
return -1; dst_vplane, dst_vstride,
src_width, src_height, BGRAToI420Row_C);
uint8* yStartPtr;
uint8* yStartPtr2;
uint8* uStartPtr;
uint8* vStartPtr;
const uint8* inpPtr;
const uint8* inpPtr2;
int h, w;
// Assuming RGB in a bottom up orientation.
yStartPtr = dst_yplane;
yStartPtr2 = yStartPtr + dst_ystride;
uStartPtr = dst_uplane;
vStartPtr = dst_vplane;
inpPtr = src_frame + src_stride * src_height * 3 - 3 * src_height;
inpPtr2 = inpPtr - 3 * src_stride;
for (h = 0; h < ((src_height + 1) >> 1); h++ ){
for (w = 0; w < ((src_width + 1) >> 1); w++){
// Y
yStartPtr[0] = (uint8)((66 * inpPtr[1] + 129 * inpPtr[2]
+ 25 * inpPtr[3] + 128) >> 8) + 16;
yStartPtr2[0] = (uint8)((66 * inpPtr2[1] + 129 * inpPtr2[2]
+ 25 * inpPtr2[3] + 128) >> 8) + 16;
// Moving to next column
yStartPtr[1] = (uint8)((66 * inpPtr[5] + 129 * inpPtr[6]
+ 25 * inpPtr[7] + 128) >> 8) + 16;
yStartPtr2[1] = (uint8)((66 * inpPtr2[5] + 129 * inpPtr2[6]
+ 25 * inpPtr2[7] + 128) >> 8 ) + 16;
// U
uStartPtr[0] = (uint8)((-38 * inpPtr[1] - 74 * inpPtr[2] +
112 * inpPtr[3] + 128) >> 8) + 128;
// V
vStartPtr[0] = (uint8)((112 * inpPtr[1] -94 * inpPtr[2] -
18 * inpPtr[3] + 128) >> 8) + 128;
yStartPtr += 2;
yStartPtr2 += 2;
uStartPtr++;
vStartPtr++;
inpPtr += 6;
inpPtr2 += 6;
} // end for w
yStartPtr += dst_ystride + dst_ystride - src_width;
yStartPtr2 += dst_ystride + dst_ystride - src_width;
uStartPtr += dst_ustride + dst_ustride - ((src_width + 1) >> 1);
vStartPtr += dst_vstride + dst_vstride - ((src_width + 1) >> 1);
inpPtr -= 3 * (2 * src_stride + src_width);
inpPtr2 -= 3 * (2 * src_stride + src_width);
} // end for h
return 0;
} }
int int
Convert::ARGBToI420(const uint8* src_frame, int src_stride, ABGRToI420(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) {
{ return RGBToI420(src_frame, src_stride,
if (src_frame == NULL || dst_yplane == NULL || dst_yplane, dst_ystride,
dst_vplane == NULL || dst_vplane == NULL) dst_uplane, dst_ustride,
return -1; dst_vplane, dst_vstride,
src_width, src_height, ABGRToI420Row_C);
uint8* yStartPtr;
uint8* yStartPtr2;
uint8* uStartPtr;
uint8* vStartPtr;
const uint8* inpPtr;
const uint8* inpPtr2;
int h, w;
yStartPtr = dst_yplane;
yStartPtr2 = yStartPtr + dst_ystride;
uStartPtr = dst_uplane;
vStartPtr = dst_vplane;
inpPtr = src_frame + src_stride * src_height * 3 - 3 * src_height;
inpPtr2 = inpPtr - 3 * src_stride;
for (h = 0; h < ((src_height + 1) >> 1); h++ ){
for (w = 0; w < ((src_width + 1) >> 1); w++){
// Y
yStartPtr[0] = (uint8)((66 * inpPtr[2] + 129 * inpPtr[1]
+ 25 * inpPtr[0] + 128) >> 8) + 16;
yStartPtr2[0] = (uint8)((66 * inpPtr2[2] + 129 * inpPtr2[1]
+ 25 * inpPtr2[0] + 128) >> 8) + 16;
// Moving to next column
yStartPtr[1] = (uint8)((66 * inpPtr[6] + 129 * inpPtr[5]
+ 25 * inpPtr[4] + 128) >> 8) + 16;
yStartPtr2[1] = (uint8)((66 * inpPtr2[5] + 129 * inpPtr2[4]
+ 25 * inpPtr2[3] + 128) >> 8 ) + 16;
// U
uStartPtr[0] = (uint8)((-38 * inpPtr[2] - 74 * inpPtr[1] +
112 * inpPtr[0] + 128) >> 8) + 128;
// V
vStartPtr[0] = (uint8)((112 * inpPtr[2] -94 * inpPtr[1] -
18 * inpPtr[0] + 128) >> 8) + 128;
yStartPtr += 2;
yStartPtr2 += 2;
uStartPtr++;
vStartPtr++;
inpPtr += 6;
inpPtr2 += 6;
} // end for w
yStartPtr += dst_ystride + dst_ystride - src_width;
yStartPtr2 += dst_ystride + dst_ystride - src_width;
uStartPtr += dst_ustride + dst_ustride - ((src_width + 1) >> 1);
vStartPtr += dst_vstride + dst_vstride - ((src_width + 1) >> 1);
inpPtr -= 3 * (2 * src_stride + src_width);
inpPtr2 -= 3 * (2 * src_stride + src_width);
} // end for h
return 0;
} }
int int
Convert::ABGRToI420(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) {
{ return RGBToI420(src_frame, src_stride,
if (src_frame == NULL || dst_yplane == NULL || dst_yplane, dst_ystride,
dst_vplane == NULL || dst_vplane == NULL){ dst_uplane, dst_ustride,
return -1; dst_vplane, dst_vstride,
} src_width, src_height, RGB24ToI420Row_C);
}
uint8* yStartPtr;
uint8* yStartPtr2;
uint8* uStartPtr;
uint8* vStartPtr;
const uint8* inpPtr;
const uint8* inpPtr2;
yStartPtr = dst_yplane;
yStartPtr2 = yStartPtr + dst_ystride;
uStartPtr = dst_uplane;
vStartPtr = dst_vplane;
inpPtr = src_frame;
inpPtr2 = inpPtr + 4 * src_stride;
int h, w;
// RGBA in memory
for (h = 0; h < ((src_height + 1) >> 1); h++){
for (w = 0; w < ((src_width + 1) >> 1); w++){
// Y
yStartPtr[0] = (uint8)((66 * inpPtr[0] + 129 * inpPtr[1]
+ 25 * inpPtr[2] + 128) >> 8) + 16;
yStartPtr2[0] = (uint8)((66 * inpPtr2[0] + 129 * inpPtr2[1]
+ 25 * inpPtr2[2] + 128) >> 8) + 16;
// Moving to next column
yStartPtr[1] = (uint8)((66 * inpPtr[4] + 129 * inpPtr[5]
+ 25 * inpPtr[6] + 128) >> 8) + 16;
yStartPtr2[1] = (uint8)((66 * inpPtr2[4] + 129 * inpPtr2[5]
+ 25 * inpPtr2[6] + 128) >> 8) + 16;
// U
uStartPtr[0] = (uint8)((-38 * inpPtr[0] - 74 * inpPtr[1]
+ 112 * inpPtr[2] + 128) >> 8) + 128;
// V
vStartPtr[0] = (uint8)((112 * inpPtr[0] - 94 * inpPtr[1]
- 18 * inpPtr[2] + 128) >> 8) + 128;
yStartPtr += 2;
yStartPtr2 += 2;
uStartPtr++;
vStartPtr++;
inpPtr += 8;
inpPtr2 += 8;
}
yStartPtr += 2 * dst_ystride - src_width; int
yStartPtr2 += 2 * dst_ystride - src_width; RAWToI420(const uint8* src_frame, int src_stride,
uStartPtr += dst_ustride + dst_ustride - ((src_width + 1) >> 1); uint8* dst_yplane, int dst_ystride,
vStartPtr += dst_vstride + dst_vstride - ((src_width + 1) >> 1); uint8* dst_uplane, int dst_ustride,
inpPtr += 4 * (2 * src_stride - src_width); uint8* dst_vplane, int dst_vstride,
inpPtr2 += 4 * (2 * src_stride - src_width); int src_width, int src_height) {
} return RGBToI420(src_frame, src_stride,
return 0; dst_yplane, dst_ystride,
dst_uplane, dst_ustride,
dst_vplane, dst_vstride,
src_width, src_height, RAWToI420Row_C);
} }
inline inline
...@@ -1328,4 +991,3 @@ void ...@@ -1328,4 +991,3 @@ void
#endif #endif
} // namespace libyuv } // namespace libyuv
...@@ -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;
......
...@@ -249,13 +249,13 @@ static void I420CopyPlane2(const uint8* src, int src_pitch_0, int src_pitch_1, ...@@ -249,13 +249,13 @@ static void I420CopyPlane2(const uint8* src, int src_pitch_0, int src_pitch_1,
// Helper function to copy yuv data without scaling. Used // Helper function to copy yuv data without scaling. Used
// by our jpeg conversion callbacks to incrementally fill a yuv image. // by our jpeg conversion callbacks to incrementally fill a yuv image.
void PlanarFunctions::I420Copy(const uint8* src_y, int src_pitch_y, void I420Copy(const uint8* src_y, int src_pitch_y,
const uint8* src_u, int src_pitch_u, const uint8* src_u, int src_pitch_u,
const uint8* src_v, int src_pitch_v, const uint8* src_v, int src_pitch_v,
uint8* dst_y, int dst_pitch_y, uint8* dst_y, int dst_pitch_y,
uint8* dst_u, int dst_pitch_u, uint8* dst_u, int dst_pitch_u,
uint8* dst_v, int dst_pitch_v, uint8* dst_v, int dst_pitch_v,
int width, int height) { int width, int height) {
// Negative height means invert the image. // Negative height means invert the image.
if (height < 0) { if (height < 0) {
height = -height; height = -height;
...@@ -276,13 +276,13 @@ void PlanarFunctions::I420Copy(const uint8* src_y, int src_pitch_y, ...@@ -276,13 +276,13 @@ void PlanarFunctions::I420Copy(const uint8* src_y, int src_pitch_y,
// Helper function to copy yuv data without scaling. Used // Helper function to copy yuv data without scaling. Used
// by our jpeg conversion callbacks to incrementally fill a yuv image. // by our jpeg conversion callbacks to incrementally fill a yuv image.
void PlanarFunctions::I422ToI420(const uint8* src_y, int src_pitch_y, void I422ToI420(const uint8* src_y, int src_pitch_y,
const uint8* src_u, int src_pitch_u, const uint8* src_u, int src_pitch_u,
const uint8* src_v, int src_pitch_v, const uint8* src_v, int src_pitch_v,
uint8* dst_y, int dst_pitch_y, uint8* dst_y, int dst_pitch_y,
uint8* dst_u, int dst_pitch_u, uint8* dst_u, int dst_pitch_u,
uint8* dst_v, int dst_pitch_v, uint8* dst_v, int dst_pitch_v,
int width, int height) { int width, int height) {
// Negative height means invert the image. // Negative height means invert the image.
if (height < 0) { if (height < 0) {
height = -height; height = -height;
...@@ -399,11 +399,11 @@ static void X420ToI420(const uint8* src_y, ...@@ -399,11 +399,11 @@ static void X420ToI420(const uint8* src_y,
} }
// Convert M420 to I420. // Convert M420 to I420.
void PlanarFunctions::M420ToI420(const uint8* src_m420, int src_pitch_m420, void M420ToI420(const uint8* src_m420, int src_pitch_m420,
uint8* dst_y, int dst_pitch_y, uint8* dst_y, int dst_pitch_y,
uint8* dst_u, int dst_pitch_u, uint8* dst_u, int dst_pitch_u,
uint8* dst_v, int dst_pitch_v, uint8* dst_v, int dst_pitch_v,
int width, int height) { int width, int height) {
X420ToI420(src_m420, src_pitch_m420, src_pitch_m420 * 2, X420ToI420(src_m420, src_pitch_m420, src_pitch_m420 * 2,
src_m420 + src_pitch_m420 * 2, src_pitch_m420 * 3, src_m420 + src_pitch_m420 * 2, src_pitch_m420 * 3,
dst_y, dst_pitch_y, dst_u, dst_pitch_u, dst_v, dst_pitch_v, dst_y, dst_pitch_y, dst_u, dst_pitch_u, dst_v, dst_pitch_v,
...@@ -411,13 +411,13 @@ void PlanarFunctions::M420ToI420(const uint8* src_m420, int src_pitch_m420, ...@@ -411,13 +411,13 @@ void PlanarFunctions::M420ToI420(const uint8* src_m420, int src_pitch_m420,
} }
// Convert NV12 to I420. // Convert NV12 to I420.
void PlanarFunctions::NV12ToI420(const uint8* src_y, void NV12ToI420(const uint8* src_y,
const uint8* src_uv, const uint8* src_uv,
int src_pitch, int src_pitch,
uint8* dst_y, int dst_pitch_y, uint8* dst_y, int dst_pitch_y,
uint8* dst_u, int dst_pitch_u, uint8* dst_u, int dst_pitch_u,
uint8* dst_v, int dst_pitch_v, uint8* dst_v, int dst_pitch_v,
int width, int height) { int width, int height) {
X420ToI420(src_y, src_pitch, src_pitch, X420ToI420(src_y, src_pitch, src_pitch,
src_uv, src_pitch, src_uv, src_pitch,
dst_y, dst_pitch_y, dst_u, dst_pitch_u, dst_v, dst_pitch_v, dst_y, dst_pitch_y, dst_u, dst_pitch_u, dst_v, dst_pitch_v,
...@@ -543,12 +543,12 @@ static void SplitYUY2_C(const uint8* src_yuy2, ...@@ -543,12 +543,12 @@ static void SplitYUY2_C(const uint8* src_yuy2,
// Convert Q420 to I420. // Convert Q420 to I420.
// Format is rows of YY/YUYV // Format is rows of YY/YUYV
void PlanarFunctions::Q420ToI420(const uint8* src_y, int src_pitch_y, void Q420ToI420(const uint8* src_y, int src_pitch_y,
const uint8* src_yuy2, int src_pitch_yuy2, const uint8* src_yuy2, int src_pitch_yuy2,
uint8* dst_y, int dst_pitch_y, uint8* dst_y, int dst_pitch_y,
uint8* dst_u, int dst_pitch_u, uint8* dst_u, int dst_pitch_u,
uint8* dst_v, int dst_pitch_v, uint8* dst_v, int dst_pitch_v,
int width, int height) { int width, int height) {
void (*SplitYUY2)(const uint8* src_yuy2, void (*SplitYUY2)(const uint8* src_yuy2,
uint8* dst_y, uint8* dst_u, uint8* dst_v, int pix); uint8* dst_y, uint8* dst_u, uint8* dst_v, int pix);
#if defined(HAS_SPLITYUY2_SSE2) #if defined(HAS_SPLITYUY2_SSE2)
...@@ -921,11 +921,11 @@ void UYVYToI420RowY_C(const uint8* src_uyvy, ...@@ -921,11 +921,11 @@ void UYVYToI420RowY_C(const uint8* src_uyvy,
} }
// Convert YUY2 to I420. // Convert YUY2 to I420.
void PlanarFunctions::YUY2ToI420(const uint8* src_yuy2, int src_pitch_yuy2, void YUY2ToI420(const uint8* src_yuy2, int src_pitch_yuy2,
uint8* dst_y, int dst_pitch_y, uint8* dst_y, int dst_pitch_y,
uint8* dst_u, int dst_pitch_u, uint8* dst_u, int dst_pitch_u,
uint8* dst_v, int dst_pitch_v, uint8* dst_v, int dst_pitch_v,
int width, int height) { int width, int height) {
void (*YUY2ToI420RowUV)(const uint8* src_yuy2, int src_pitch_yuy2, void (*YUY2ToI420RowUV)(const uint8* src_yuy2, int src_pitch_yuy2,
uint8* dst_u, uint8* dst_v, int pix); uint8* dst_u, uint8* dst_v, int pix);
void (*YUY2ToI420RowY)(const uint8* src_yuy2, void (*YUY2ToI420RowY)(const uint8* src_yuy2,
...@@ -961,11 +961,11 @@ void PlanarFunctions::YUY2ToI420(const uint8* src_yuy2, int src_pitch_yuy2, ...@@ -961,11 +961,11 @@ void PlanarFunctions::YUY2ToI420(const uint8* src_yuy2, int src_pitch_yuy2,
} }
// Convert UYVY to I420. // Convert UYVY to I420.
void PlanarFunctions::UYVYToI420(const uint8* src_uyvy, int src_pitch_uyvy, void UYVYToI420(const uint8* src_uyvy, int src_pitch_uyvy,
uint8* dst_y, int dst_pitch_y, uint8* dst_y, int dst_pitch_y,
uint8* dst_u, int dst_pitch_u, uint8* dst_u, int dst_pitch_u,
uint8* dst_v, int dst_pitch_v, uint8* dst_v, int dst_pitch_v,
int width, int height) { int width, int height) {
void (*UYVYToI420RowUV)(const uint8* src_uyvy, int src_pitch_uyvy, void (*UYVYToI420RowUV)(const uint8* src_uyvy, int src_pitch_uyvy,
uint8* dst_u, uint8* dst_v, int pix); uint8* dst_u, uint8* dst_v, int pix);
void (*UYVYToI420RowY)(const uint8* src_uyvy, void (*UYVYToI420RowY)(const uint8* src_uyvy,
...@@ -1002,11 +1002,11 @@ void PlanarFunctions::UYVYToI420(const uint8* src_uyvy, int src_pitch_uyvy, ...@@ -1002,11 +1002,11 @@ void PlanarFunctions::UYVYToI420(const uint8* src_uyvy, int src_pitch_uyvy,
// Convert I420 to ARGB. // Convert I420 to ARGB.
// TODO(fbarchard): Add SSSE3 version and supply C version for fallback. // TODO(fbarchard): Add SSSE3 version and supply C version for fallback.
void PlanarFunctions::I420ToARGB(const uint8* src_y, int src_pitch_y, void I420ToARGB(const uint8* src_y, int src_pitch_y,
const uint8* src_u, int src_pitch_u, const uint8* src_u, int src_pitch_u,
const uint8* src_v, int src_pitch_v, const uint8* src_v, int src_pitch_v,
uint8* dst_argb, int dst_pitch_argb, uint8* dst_argb, int dst_pitch_argb,
int width, int height) { int width, int height) {
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
FastConvertYUVToRGB32Row(src_y, src_u, src_v, dst_argb, width); FastConvertYUVToRGB32Row(src_y, src_u, src_v, dst_argb, width);
dst_argb += dst_pitch_argb; dst_argb += dst_pitch_argb;
...@@ -1020,12 +1020,48 @@ void PlanarFunctions::I420ToARGB(const uint8* src_y, int src_pitch_y, ...@@ -1020,12 +1020,48 @@ void PlanarFunctions::I420ToARGB(const uint8* src_y, int src_pitch_y,
EMMS(); EMMS();
} }
// 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) {
for (int y = 0; y < height; ++y) {
FastConvertYUVToBGRARow(src_y, src_u, src_v, dst_argb, width);
dst_argb += dst_pitch_argb;
src_y += src_pitch_y;
if (y & 1) {
src_u += src_pitch_u;
src_v += src_pitch_v;
}
}
EMMS();
}
// Convert I420 to BGRA.
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) {
for (int y = 0; y < height; ++y) {
FastConvertYUVToABGRRow(src_y, src_u, src_v, dst_argb, width);
dst_argb += dst_pitch_argb;
src_y += src_pitch_y;
if (y & 1) {
src_u += src_pitch_u;
src_v += src_pitch_v;
}
}
EMMS();
}
// Convert I422 to ARGB. // Convert I422 to ARGB.
void PlanarFunctions::I422ToARGB(const uint8* src_y, int src_pitch_y, void I422ToARGB(const uint8* src_y, int src_pitch_y,
const uint8* src_u, int src_pitch_u, const uint8* src_u, int src_pitch_u,
const uint8* src_v, int src_pitch_v, const uint8* src_v, int src_pitch_v,
uint8* dst_argb, int dst_pitch_argb, uint8* dst_argb, int dst_pitch_argb,
int width, int height) { int width, int height) {
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
FastConvertYUVToRGB32Row(src_y, src_u, src_v, dst_argb, width); FastConvertYUVToRGB32Row(src_y, src_u, src_v, dst_argb, width);
dst_argb += dst_pitch_argb; dst_argb += dst_pitch_argb;
...@@ -1038,11 +1074,11 @@ void PlanarFunctions::I422ToARGB(const uint8* src_y, int src_pitch_y, ...@@ -1038,11 +1074,11 @@ void PlanarFunctions::I422ToARGB(const uint8* src_y, int src_pitch_y,
} }
// Convert I444 to ARGB. // Convert I444 to ARGB.
void PlanarFunctions::I444ToARGB(const uint8* src_y, int src_pitch_y, void I444ToARGB(const uint8* src_y, int src_pitch_y,
const uint8* src_u, int src_pitch_u, const uint8* src_u, int src_pitch_u,
const uint8* src_v, int src_pitch_v, const uint8* src_v, int src_pitch_v,
uint8* dst_argb, int dst_pitch_argb, uint8* dst_argb, int dst_pitch_argb,
int width, int height) { int width, int height) {
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
FastConvertYUV444ToRGB32Row(src_y, src_u, src_v, dst_argb, width); FastConvertYUV444ToRGB32Row(src_y, src_u, src_v, dst_argb, width);
dst_argb += dst_pitch_argb; dst_argb += dst_pitch_argb;
...@@ -1055,9 +1091,9 @@ void PlanarFunctions::I444ToARGB(const uint8* src_y, int src_pitch_y, ...@@ -1055,9 +1091,9 @@ void PlanarFunctions::I444ToARGB(const uint8* src_y, int src_pitch_y,
} }
// Convert I400 to ARGB. // Convert I400 to ARGB.
void PlanarFunctions::I400ToARGB_Reference(const uint8* src_y, int src_pitch_y, 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) {
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
FastConvertYToRGB32Row(src_y, dst_argb, width); FastConvertYToRGB32Row(src_y, dst_argb, width);
dst_argb += dst_pitch_argb; dst_argb += dst_pitch_argb;
...@@ -1147,9 +1183,9 @@ static void I400ToARGBRow_C(const uint8* src_y, uint8* dst_argb, int pix) { ...@@ -1147,9 +1183,9 @@ static void I400ToARGBRow_C(const uint8* src_y, uint8* dst_argb, int pix) {
} }
// Convert I400 to ARGB. // Convert I400 to ARGB.
void PlanarFunctions::I400ToARGB(const uint8* src_y, int src_pitch_y, 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) {
void (*I400ToARGBRow)(const uint8* src_y, uint8* dst_argb, int pix); void (*I400ToARGBRow)(const uint8* src_y, uint8* dst_argb, int pix);
#if defined(HAS_I400TOARGBROW_SSE2) #if defined(HAS_I400TOARGBROW_SSE2)
if (libyuv::CpuInfo::TestCpuFlag(libyuv::CpuInfo::kCpuHasSSE2) && if (libyuv::CpuInfo::TestCpuFlag(libyuv::CpuInfo::kCpuHasSSE2) &&
...@@ -1182,9 +1218,9 @@ static void RAWToARGBRow_C(const uint8* src_raw, uint8* dst_argb, int pix) { ...@@ -1182,9 +1218,9 @@ static void RAWToARGBRow_C(const uint8* src_raw, uint8* dst_argb, int pix) {
} }
// Convert RAW to ARGB. // Convert RAW to ARGB.
void PlanarFunctions::RAWToARGB(const uint8* src_raw, int src_pitch_raw, 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) {
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
RAWToARGBRow_C(src_raw, dst_argb, width); RAWToARGBRow_C(src_raw, dst_argb, width);
src_raw += src_pitch_raw; src_raw += src_pitch_raw;
...@@ -1204,9 +1240,9 @@ static void BG24ToARGBRow_C(const uint8* src_bg24, uint8* dst_argb, int pix) { ...@@ -1204,9 +1240,9 @@ static void BG24ToARGBRow_C(const uint8* src_bg24, uint8* dst_argb, int pix) {
} }
// Convert BG24 to ARGB. // Convert BG24 to ARGB.
void PlanarFunctions::BG24ToARGB(const uint8* src_bg24, int src_pitch_bg24, 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) {
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
BG24ToARGBRow_C(src_bg24, dst_argb, width); BG24ToARGBRow_C(src_bg24, dst_argb, width);
src_bg24 += src_pitch_bg24; src_bg24 += src_pitch_bg24;
...@@ -1226,9 +1262,9 @@ static void ABGRToARGBRow_C(const uint8* src_abgr, uint8* dst_argb, int pix) { ...@@ -1226,9 +1262,9 @@ static void ABGRToARGBRow_C(const uint8* src_abgr, uint8* dst_argb, int pix) {
} }
// Convert ABGR to ARGB. // Convert ABGR to ARGB.
void PlanarFunctions::ABGRToARGB(const uint8* src_abgr, int src_pitch_abgr, void ABGRToARGB(const uint8* src_abgr, int src_pitch_abgr,
uint8* dst_argb, int dst_pitch_argb, uint8* dst_argb, int dst_pitch_argb,
int width, int height) { int width, int height) {
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
ABGRToARGBRow_C(src_abgr, dst_argb, width); ABGRToARGBRow_C(src_abgr, dst_argb, width);
src_abgr += src_pitch_abgr; src_abgr += src_pitch_abgr;
......
...@@ -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.
} }
......
...@@ -12,6 +12,203 @@ ...@@ -12,6 +12,203 @@
extern "C" { extern "C" {
#define MAKETABLE(NAME) \
SIMD_ALIGNED(const int16 NAME[256 * 3][4]) = {\
RGBY(0x00), RGBY(0x01), RGBY(0x02), RGBY(0x03), \
RGBY(0x04), RGBY(0x05), RGBY(0x06), RGBY(0x07), \
RGBY(0x08), RGBY(0x09), RGBY(0x0A), RGBY(0x0B), \
RGBY(0x0C), RGBY(0x0D), RGBY(0x0E), RGBY(0x0F), \
RGBY(0x10), RGBY(0x11), RGBY(0x12), RGBY(0x13), \
RGBY(0x14), RGBY(0x15), RGBY(0x16), RGBY(0x17), \
RGBY(0x18), RGBY(0x19), RGBY(0x1A), RGBY(0x1B), \
RGBY(0x1C), RGBY(0x1D), RGBY(0x1E), RGBY(0x1F), \
RGBY(0x20), RGBY(0x21), RGBY(0x22), RGBY(0x23), \
RGBY(0x24), RGBY(0x25), RGBY(0x26), RGBY(0x27), \
RGBY(0x28), RGBY(0x29), RGBY(0x2A), RGBY(0x2B), \
RGBY(0x2C), RGBY(0x2D), RGBY(0x2E), RGBY(0x2F), \
RGBY(0x30), RGBY(0x31), RGBY(0x32), RGBY(0x33), \
RGBY(0x34), RGBY(0x35), RGBY(0x36), RGBY(0x37), \
RGBY(0x38), RGBY(0x39), RGBY(0x3A), RGBY(0x3B), \
RGBY(0x3C), RGBY(0x3D), RGBY(0x3E), RGBY(0x3F), \
RGBY(0x40), RGBY(0x41), RGBY(0x42), RGBY(0x43), \
RGBY(0x44), RGBY(0x45), RGBY(0x46), RGBY(0x47), \
RGBY(0x48), RGBY(0x49), RGBY(0x4A), RGBY(0x4B), \
RGBY(0x4C), RGBY(0x4D), RGBY(0x4E), RGBY(0x4F), \
RGBY(0x50), RGBY(0x51), RGBY(0x52), RGBY(0x53), \
RGBY(0x54), RGBY(0x55), RGBY(0x56), RGBY(0x57), \
RGBY(0x58), RGBY(0x59), RGBY(0x5A), RGBY(0x5B), \
RGBY(0x5C), RGBY(0x5D), RGBY(0x5E), RGBY(0x5F), \
RGBY(0x60), RGBY(0x61), RGBY(0x62), RGBY(0x63), \
RGBY(0x64), RGBY(0x65), RGBY(0x66), RGBY(0x67), \
RGBY(0x68), RGBY(0x69), RGBY(0x6A), RGBY(0x6B), \
RGBY(0x6C), RGBY(0x6D), RGBY(0x6E), RGBY(0x6F), \
RGBY(0x70), RGBY(0x71), RGBY(0x72), RGBY(0x73), \
RGBY(0x74), RGBY(0x75), RGBY(0x76), RGBY(0x77), \
RGBY(0x78), RGBY(0x79), RGBY(0x7A), RGBY(0x7B), \
RGBY(0x7C), RGBY(0x7D), RGBY(0x7E), RGBY(0x7F), \
RGBY(0x80), RGBY(0x81), RGBY(0x82), RGBY(0x83), \
RGBY(0x84), RGBY(0x85), RGBY(0x86), RGBY(0x87), \
RGBY(0x88), RGBY(0x89), RGBY(0x8A), RGBY(0x8B), \
RGBY(0x8C), RGBY(0x8D), RGBY(0x8E), RGBY(0x8F), \
RGBY(0x90), RGBY(0x91), RGBY(0x92), RGBY(0x93), \
RGBY(0x94), RGBY(0x95), RGBY(0x96), RGBY(0x97), \
RGBY(0x98), RGBY(0x99), RGBY(0x9A), RGBY(0x9B), \
RGBY(0x9C), RGBY(0x9D), RGBY(0x9E), RGBY(0x9F), \
RGBY(0xA0), RGBY(0xA1), RGBY(0xA2), RGBY(0xA3), \
RGBY(0xA4), RGBY(0xA5), RGBY(0xA6), RGBY(0xA7), \
RGBY(0xA8), RGBY(0xA9), RGBY(0xAA), RGBY(0xAB), \
RGBY(0xAC), RGBY(0xAD), RGBY(0xAE), RGBY(0xAF), \
RGBY(0xB0), RGBY(0xB1), RGBY(0xB2), RGBY(0xB3), \
RGBY(0xB4), RGBY(0xB5), RGBY(0xB6), RGBY(0xB7), \
RGBY(0xB8), RGBY(0xB9), RGBY(0xBA), RGBY(0xBB), \
RGBY(0xBC), RGBY(0xBD), RGBY(0xBE), RGBY(0xBF), \
RGBY(0xC0), RGBY(0xC1), RGBY(0xC2), RGBY(0xC3), \
RGBY(0xC4), RGBY(0xC5), RGBY(0xC6), RGBY(0xC7), \
RGBY(0xC8), RGBY(0xC9), RGBY(0xCA), RGBY(0xCB), \
RGBY(0xCC), RGBY(0xCD), RGBY(0xCE), RGBY(0xCF), \
RGBY(0xD0), RGBY(0xD1), RGBY(0xD2), RGBY(0xD3), \
RGBY(0xD4), RGBY(0xD5), RGBY(0xD6), RGBY(0xD7), \
RGBY(0xD8), RGBY(0xD9), RGBY(0xDA), RGBY(0xDB), \
RGBY(0xDC), RGBY(0xDD), RGBY(0xDE), RGBY(0xDF), \
RGBY(0xE0), RGBY(0xE1), RGBY(0xE2), RGBY(0xE3), \
RGBY(0xE4), RGBY(0xE5), RGBY(0xE6), RGBY(0xE7), \
RGBY(0xE8), RGBY(0xE9), RGBY(0xEA), RGBY(0xEB), \
RGBY(0xEC), RGBY(0xED), RGBY(0xEE), RGBY(0xEF), \
RGBY(0xF0), RGBY(0xF1), RGBY(0xF2), RGBY(0xF3), \
RGBY(0xF4), RGBY(0xF5), RGBY(0xF6), RGBY(0xF7), \
RGBY(0xF8), RGBY(0xF9), RGBY(0xFA), RGBY(0xFB), \
RGBY(0xFC), RGBY(0xFD), RGBY(0xFE), RGBY(0xFF), \
RGBU(0x00), RGBU(0x01), RGBU(0x02), RGBU(0x03), \
RGBU(0x04), RGBU(0x05), RGBU(0x06), RGBU(0x07), \
RGBU(0x08), RGBU(0x09), RGBU(0x0A), RGBU(0x0B), \
RGBU(0x0C), RGBU(0x0D), RGBU(0x0E), RGBU(0x0F), \
RGBU(0x10), RGBU(0x11), RGBU(0x12), RGBU(0x13), \
RGBU(0x14), RGBU(0x15), RGBU(0x16), RGBU(0x17), \
RGBU(0x18), RGBU(0x19), RGBU(0x1A), RGBU(0x1B), \
RGBU(0x1C), RGBU(0x1D), RGBU(0x1E), RGBU(0x1F), \
RGBU(0x20), RGBU(0x21), RGBU(0x22), RGBU(0x23), \
RGBU(0x24), RGBU(0x25), RGBU(0x26), RGBU(0x27), \
RGBU(0x28), RGBU(0x29), RGBU(0x2A), RGBU(0x2B), \
RGBU(0x2C), RGBU(0x2D), RGBU(0x2E), RGBU(0x2F), \
RGBU(0x30), RGBU(0x31), RGBU(0x32), RGBU(0x33), \
RGBU(0x34), RGBU(0x35), RGBU(0x36), RGBU(0x37), \
RGBU(0x38), RGBU(0x39), RGBU(0x3A), RGBU(0x3B), \
RGBU(0x3C), RGBU(0x3D), RGBU(0x3E), RGBU(0x3F), \
RGBU(0x40), RGBU(0x41), RGBU(0x42), RGBU(0x43), \
RGBU(0x44), RGBU(0x45), RGBU(0x46), RGBU(0x47), \
RGBU(0x48), RGBU(0x49), RGBU(0x4A), RGBU(0x4B), \
RGBU(0x4C), RGBU(0x4D), RGBU(0x4E), RGBU(0x4F), \
RGBU(0x50), RGBU(0x51), RGBU(0x52), RGBU(0x53), \
RGBU(0x54), RGBU(0x55), RGBU(0x56), RGBU(0x57), \
RGBU(0x58), RGBU(0x59), RGBU(0x5A), RGBU(0x5B), \
RGBU(0x5C), RGBU(0x5D), RGBU(0x5E), RGBU(0x5F), \
RGBU(0x60), RGBU(0x61), RGBU(0x62), RGBU(0x63), \
RGBU(0x64), RGBU(0x65), RGBU(0x66), RGBU(0x67), \
RGBU(0x68), RGBU(0x69), RGBU(0x6A), RGBU(0x6B), \
RGBU(0x6C), RGBU(0x6D), RGBU(0x6E), RGBU(0x6F), \
RGBU(0x70), RGBU(0x71), RGBU(0x72), RGBU(0x73), \
RGBU(0x74), RGBU(0x75), RGBU(0x76), RGBU(0x77), \
RGBU(0x78), RGBU(0x79), RGBU(0x7A), RGBU(0x7B), \
RGBU(0x7C), RGBU(0x7D), RGBU(0x7E), RGBU(0x7F), \
RGBU(0x80), RGBU(0x81), RGBU(0x82), RGBU(0x83), \
RGBU(0x84), RGBU(0x85), RGBU(0x86), RGBU(0x87), \
RGBU(0x88), RGBU(0x89), RGBU(0x8A), RGBU(0x8B), \
RGBU(0x8C), RGBU(0x8D), RGBU(0x8E), RGBU(0x8F), \
RGBU(0x90), RGBU(0x91), RGBU(0x92), RGBU(0x93), \
RGBU(0x94), RGBU(0x95), RGBU(0x96), RGBU(0x97), \
RGBU(0x98), RGBU(0x99), RGBU(0x9A), RGBU(0x9B), \
RGBU(0x9C), RGBU(0x9D), RGBU(0x9E), RGBU(0x9F), \
RGBU(0xA0), RGBU(0xA1), RGBU(0xA2), RGBU(0xA3), \
RGBU(0xA4), RGBU(0xA5), RGBU(0xA6), RGBU(0xA7), \
RGBU(0xA8), RGBU(0xA9), RGBU(0xAA), RGBU(0xAB), \
RGBU(0xAC), RGBU(0xAD), RGBU(0xAE), RGBU(0xAF), \
RGBU(0xB0), RGBU(0xB1), RGBU(0xB2), RGBU(0xB3), \
RGBU(0xB4), RGBU(0xB5), RGBU(0xB6), RGBU(0xB7), \
RGBU(0xB8), RGBU(0xB9), RGBU(0xBA), RGBU(0xBB), \
RGBU(0xBC), RGBU(0xBD), RGBU(0xBE), RGBU(0xBF), \
RGBU(0xC0), RGBU(0xC1), RGBU(0xC2), RGBU(0xC3), \
RGBU(0xC4), RGBU(0xC5), RGBU(0xC6), RGBU(0xC7), \
RGBU(0xC8), RGBU(0xC9), RGBU(0xCA), RGBU(0xCB), \
RGBU(0xCC), RGBU(0xCD), RGBU(0xCE), RGBU(0xCF), \
RGBU(0xD0), RGBU(0xD1), RGBU(0xD2), RGBU(0xD3), \
RGBU(0xD4), RGBU(0xD5), RGBU(0xD6), RGBU(0xD7), \
RGBU(0xD8), RGBU(0xD9), RGBU(0xDA), RGBU(0xDB), \
RGBU(0xDC), RGBU(0xDD), RGBU(0xDE), RGBU(0xDF), \
RGBU(0xE0), RGBU(0xE1), RGBU(0xE2), RGBU(0xE3), \
RGBU(0xE4), RGBU(0xE5), RGBU(0xE6), RGBU(0xE7), \
RGBU(0xE8), RGBU(0xE9), RGBU(0xEA), RGBU(0xEB), \
RGBU(0xEC), RGBU(0xED), RGBU(0xEE), RGBU(0xEF), \
RGBU(0xF0), RGBU(0xF1), RGBU(0xF2), RGBU(0xF3), \
RGBU(0xF4), RGBU(0xF5), RGBU(0xF6), RGBU(0xF7), \
RGBU(0xF8), RGBU(0xF9), RGBU(0xFA), RGBU(0xFB), \
RGBU(0xFC), RGBU(0xFD), RGBU(0xFE), RGBU(0xFF), \
RGBV(0x00), RGBV(0x01), RGBV(0x02), RGBV(0x03), \
RGBV(0x04), RGBV(0x05), RGBV(0x06), RGBV(0x07), \
RGBV(0x08), RGBV(0x09), RGBV(0x0A), RGBV(0x0B), \
RGBV(0x0C), RGBV(0x0D), RGBV(0x0E), RGBV(0x0F), \
RGBV(0x10), RGBV(0x11), RGBV(0x12), RGBV(0x13), \
RGBV(0x14), RGBV(0x15), RGBV(0x16), RGBV(0x17), \
RGBV(0x18), RGBV(0x19), RGBV(0x1A), RGBV(0x1B), \
RGBV(0x1C), RGBV(0x1D), RGBV(0x1E), RGBV(0x1F), \
RGBV(0x20), RGBV(0x21), RGBV(0x22), RGBV(0x23), \
RGBV(0x24), RGBV(0x25), RGBV(0x26), RGBV(0x27), \
RGBV(0x28), RGBV(0x29), RGBV(0x2A), RGBV(0x2B), \
RGBV(0x2C), RGBV(0x2D), RGBV(0x2E), RGBV(0x2F), \
RGBV(0x30), RGBV(0x31), RGBV(0x32), RGBV(0x33), \
RGBV(0x34), RGBV(0x35), RGBV(0x36), RGBV(0x37), \
RGBV(0x38), RGBV(0x39), RGBV(0x3A), RGBV(0x3B), \
RGBV(0x3C), RGBV(0x3D), RGBV(0x3E), RGBV(0x3F), \
RGBV(0x40), RGBV(0x41), RGBV(0x42), RGBV(0x43), \
RGBV(0x44), RGBV(0x45), RGBV(0x46), RGBV(0x47), \
RGBV(0x48), RGBV(0x49), RGBV(0x4A), RGBV(0x4B), \
RGBV(0x4C), RGBV(0x4D), RGBV(0x4E), RGBV(0x4F), \
RGBV(0x50), RGBV(0x51), RGBV(0x52), RGBV(0x53), \
RGBV(0x54), RGBV(0x55), RGBV(0x56), RGBV(0x57), \
RGBV(0x58), RGBV(0x59), RGBV(0x5A), RGBV(0x5B), \
RGBV(0x5C), RGBV(0x5D), RGBV(0x5E), RGBV(0x5F), \
RGBV(0x60), RGBV(0x61), RGBV(0x62), RGBV(0x63), \
RGBV(0x64), RGBV(0x65), RGBV(0x66), RGBV(0x67), \
RGBV(0x68), RGBV(0x69), RGBV(0x6A), RGBV(0x6B), \
RGBV(0x6C), RGBV(0x6D), RGBV(0x6E), RGBV(0x6F), \
RGBV(0x70), RGBV(0x71), RGBV(0x72), RGBV(0x73), \
RGBV(0x74), RGBV(0x75), RGBV(0x76), RGBV(0x77), \
RGBV(0x78), RGBV(0x79), RGBV(0x7A), RGBV(0x7B), \
RGBV(0x7C), RGBV(0x7D), RGBV(0x7E), RGBV(0x7F), \
RGBV(0x80), RGBV(0x81), RGBV(0x82), RGBV(0x83), \
RGBV(0x84), RGBV(0x85), RGBV(0x86), RGBV(0x87), \
RGBV(0x88), RGBV(0x89), RGBV(0x8A), RGBV(0x8B), \
RGBV(0x8C), RGBV(0x8D), RGBV(0x8E), RGBV(0x8F), \
RGBV(0x90), RGBV(0x91), RGBV(0x92), RGBV(0x93), \
RGBV(0x94), RGBV(0x95), RGBV(0x96), RGBV(0x97), \
RGBV(0x98), RGBV(0x99), RGBV(0x9A), RGBV(0x9B), \
RGBV(0x9C), RGBV(0x9D), RGBV(0x9E), RGBV(0x9F), \
RGBV(0xA0), RGBV(0xA1), RGBV(0xA2), RGBV(0xA3), \
RGBV(0xA4), RGBV(0xA5), RGBV(0xA6), RGBV(0xA7), \
RGBV(0xA8), RGBV(0xA9), RGBV(0xAA), RGBV(0xAB), \
RGBV(0xAC), RGBV(0xAD), RGBV(0xAE), RGBV(0xAF), \
RGBV(0xB0), RGBV(0xB1), RGBV(0xB2), RGBV(0xB3), \
RGBV(0xB4), RGBV(0xB5), RGBV(0xB6), RGBV(0xB7), \
RGBV(0xB8), RGBV(0xB9), RGBV(0xBA), RGBV(0xBB), \
RGBV(0xBC), RGBV(0xBD), RGBV(0xBE), RGBV(0xBF), \
RGBV(0xC0), RGBV(0xC1), RGBV(0xC2), RGBV(0xC3), \
RGBV(0xC4), RGBV(0xC5), RGBV(0xC6), RGBV(0xC7), \
RGBV(0xC8), RGBV(0xC9), RGBV(0xCA), RGBV(0xCB), \
RGBV(0xCC), RGBV(0xCD), RGBV(0xCE), RGBV(0xCF), \
RGBV(0xD0), RGBV(0xD1), RGBV(0xD2), RGBV(0xD3), \
RGBV(0xD4), RGBV(0xD5), RGBV(0xD6), RGBV(0xD7), \
RGBV(0xD8), RGBV(0xD9), RGBV(0xDA), RGBV(0xDB), \
RGBV(0xDC), RGBV(0xDD), RGBV(0xDE), RGBV(0xDF), \
RGBV(0xE0), RGBV(0xE1), RGBV(0xE2), RGBV(0xE3), \
RGBV(0xE4), RGBV(0xE5), RGBV(0xE6), RGBV(0xE7), \
RGBV(0xE8), RGBV(0xE9), RGBV(0xEA), RGBV(0xEB), \
RGBV(0xEC), RGBV(0xED), RGBV(0xEE), RGBV(0xEF), \
RGBV(0xF0), RGBV(0xF1), RGBV(0xF2), RGBV(0xF3), \
RGBV(0xF4), RGBV(0xF5), RGBV(0xF6), RGBV(0xF7), \
RGBV(0xF8), RGBV(0xF9), RGBV(0xFA), RGBV(0xFB), \
RGBV(0xFC), RGBV(0xFD), RGBV(0xFE), RGBV(0xFF), \
};
// ARGB table
#define RGBY(i) { \ #define RGBY(i) { \
static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \ static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \ static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
...@@ -34,212 +231,74 @@ extern "C" { ...@@ -34,212 +231,74 @@ extern "C" {
} }
#ifdef OSX #ifdef OSX
SIMD_ALIGNED(const int16 kCoefficientsRgbY[256 * 3][4]) = { MAKETABLE(kCoefficientsRgbY)
#else #else
SIMD_ALIGNED(const int16 _kCoefficientsRgbY[256 * 3][4]) = { MAKETABLE(_kCoefficientsRgbY)
#endif
#undef RGBY
#undef RGBU
#undef RGBV
// BGRA table
#define RGBY(i) { \
static_cast<int16>(256 * 64 - 1), \
static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
static_cast<int16>(1.164 * 64 * (i - 16) + 0.5) \
}
#define RGBU(i) { \
0, \
0, \
static_cast<int16>(-0.391 * 64 * (i - 128) + 0.5), \
static_cast<int16>(2.018 * 64 * (i - 128) + 0.5) \
}
#define RGBV(i) { \
0, \
static_cast<int16>(1.596 * 64 * (i - 128) + 0.5), \
static_cast<int16>(-0.813 * 64 * (i - 128) + 0.5), \
0 \
}
#ifdef OSX
MAKETABLE(kCoefficientsBgraY)
#else
MAKETABLE(_kCoefficientsBgraY)
#endif #endif
// Luminance table.
RGBY(0x00), RGBY(0x01), RGBY(0x02), RGBY(0x03),
RGBY(0x04), RGBY(0x05), RGBY(0x06), RGBY(0x07),
RGBY(0x08), RGBY(0x09), RGBY(0x0A), RGBY(0x0B),
RGBY(0x0C), RGBY(0x0D), RGBY(0x0E), RGBY(0x0F),
RGBY(0x10), RGBY(0x11), RGBY(0x12), RGBY(0x13),
RGBY(0x14), RGBY(0x15), RGBY(0x16), RGBY(0x17),
RGBY(0x18), RGBY(0x19), RGBY(0x1A), RGBY(0x1B),
RGBY(0x1C), RGBY(0x1D), RGBY(0x1E), RGBY(0x1F),
RGBY(0x20), RGBY(0x21), RGBY(0x22), RGBY(0x23),
RGBY(0x24), RGBY(0x25), RGBY(0x26), RGBY(0x27),
RGBY(0x28), RGBY(0x29), RGBY(0x2A), RGBY(0x2B),
RGBY(0x2C), RGBY(0x2D), RGBY(0x2E), RGBY(0x2F),
RGBY(0x30), RGBY(0x31), RGBY(0x32), RGBY(0x33),
RGBY(0x34), RGBY(0x35), RGBY(0x36), RGBY(0x37),
RGBY(0x38), RGBY(0x39), RGBY(0x3A), RGBY(0x3B),
RGBY(0x3C), RGBY(0x3D), RGBY(0x3E), RGBY(0x3F),
RGBY(0x40), RGBY(0x41), RGBY(0x42), RGBY(0x43),
RGBY(0x44), RGBY(0x45), RGBY(0x46), RGBY(0x47),
RGBY(0x48), RGBY(0x49), RGBY(0x4A), RGBY(0x4B),
RGBY(0x4C), RGBY(0x4D), RGBY(0x4E), RGBY(0x4F),
RGBY(0x50), RGBY(0x51), RGBY(0x52), RGBY(0x53),
RGBY(0x54), RGBY(0x55), RGBY(0x56), RGBY(0x57),
RGBY(0x58), RGBY(0x59), RGBY(0x5A), RGBY(0x5B),
RGBY(0x5C), RGBY(0x5D), RGBY(0x5E), RGBY(0x5F),
RGBY(0x60), RGBY(0x61), RGBY(0x62), RGBY(0x63),
RGBY(0x64), RGBY(0x65), RGBY(0x66), RGBY(0x67),
RGBY(0x68), RGBY(0x69), RGBY(0x6A), RGBY(0x6B),
RGBY(0x6C), RGBY(0x6D), RGBY(0x6E), RGBY(0x6F),
RGBY(0x70), RGBY(0x71), RGBY(0x72), RGBY(0x73),
RGBY(0x74), RGBY(0x75), RGBY(0x76), RGBY(0x77),
RGBY(0x78), RGBY(0x79), RGBY(0x7A), RGBY(0x7B),
RGBY(0x7C), RGBY(0x7D), RGBY(0x7E), RGBY(0x7F),
RGBY(0x80), RGBY(0x81), RGBY(0x82), RGBY(0x83),
RGBY(0x84), RGBY(0x85), RGBY(0x86), RGBY(0x87),
RGBY(0x88), RGBY(0x89), RGBY(0x8A), RGBY(0x8B),
RGBY(0x8C), RGBY(0x8D), RGBY(0x8E), RGBY(0x8F),
RGBY(0x90), RGBY(0x91), RGBY(0x92), RGBY(0x93),
RGBY(0x94), RGBY(0x95), RGBY(0x96), RGBY(0x97),
RGBY(0x98), RGBY(0x99), RGBY(0x9A), RGBY(0x9B),
RGBY(0x9C), RGBY(0x9D), RGBY(0x9E), RGBY(0x9F),
RGBY(0xA0), RGBY(0xA1), RGBY(0xA2), RGBY(0xA3),
RGBY(0xA4), RGBY(0xA5), RGBY(0xA6), RGBY(0xA7),
RGBY(0xA8), RGBY(0xA9), RGBY(0xAA), RGBY(0xAB),
RGBY(0xAC), RGBY(0xAD), RGBY(0xAE), RGBY(0xAF),
RGBY(0xB0), RGBY(0xB1), RGBY(0xB2), RGBY(0xB3),
RGBY(0xB4), RGBY(0xB5), RGBY(0xB6), RGBY(0xB7),
RGBY(0xB8), RGBY(0xB9), RGBY(0xBA), RGBY(0xBB),
RGBY(0xBC), RGBY(0xBD), RGBY(0xBE), RGBY(0xBF),
RGBY(0xC0), RGBY(0xC1), RGBY(0xC2), RGBY(0xC3),
RGBY(0xC4), RGBY(0xC5), RGBY(0xC6), RGBY(0xC7),
RGBY(0xC8), RGBY(0xC9), RGBY(0xCA), RGBY(0xCB),
RGBY(0xCC), RGBY(0xCD), RGBY(0xCE), RGBY(0xCF),
RGBY(0xD0), RGBY(0xD1), RGBY(0xD2), RGBY(0xD3),
RGBY(0xD4), RGBY(0xD5), RGBY(0xD6), RGBY(0xD7),
RGBY(0xD8), RGBY(0xD9), RGBY(0xDA), RGBY(0xDB),
RGBY(0xDC), RGBY(0xDD), RGBY(0xDE), RGBY(0xDF),
RGBY(0xE0), RGBY(0xE1), RGBY(0xE2), RGBY(0xE3),
RGBY(0xE4), RGBY(0xE5), RGBY(0xE6), RGBY(0xE7),
RGBY(0xE8), RGBY(0xE9), RGBY(0xEA), RGBY(0xEB),
RGBY(0xEC), RGBY(0xED), RGBY(0xEE), RGBY(0xEF),
RGBY(0xF0), RGBY(0xF1), RGBY(0xF2), RGBY(0xF3),
RGBY(0xF4), RGBY(0xF5), RGBY(0xF6), RGBY(0xF7),
RGBY(0xF8), RGBY(0xF9), RGBY(0xFA), RGBY(0xFB),
RGBY(0xFC), RGBY(0xFD), RGBY(0xFE), RGBY(0xFF),
// Chroma U table.
RGBU(0x00), RGBU(0x01), RGBU(0x02), RGBU(0x03),
RGBU(0x04), RGBU(0x05), RGBU(0x06), RGBU(0x07),
RGBU(0x08), RGBU(0x09), RGBU(0x0A), RGBU(0x0B),
RGBU(0x0C), RGBU(0x0D), RGBU(0x0E), RGBU(0x0F),
RGBU(0x10), RGBU(0x11), RGBU(0x12), RGBU(0x13),
RGBU(0x14), RGBU(0x15), RGBU(0x16), RGBU(0x17),
RGBU(0x18), RGBU(0x19), RGBU(0x1A), RGBU(0x1B),
RGBU(0x1C), RGBU(0x1D), RGBU(0x1E), RGBU(0x1F),
RGBU(0x20), RGBU(0x21), RGBU(0x22), RGBU(0x23),
RGBU(0x24), RGBU(0x25), RGBU(0x26), RGBU(0x27),
RGBU(0x28), RGBU(0x29), RGBU(0x2A), RGBU(0x2B),
RGBU(0x2C), RGBU(0x2D), RGBU(0x2E), RGBU(0x2F),
RGBU(0x30), RGBU(0x31), RGBU(0x32), RGBU(0x33),
RGBU(0x34), RGBU(0x35), RGBU(0x36), RGBU(0x37),
RGBU(0x38), RGBU(0x39), RGBU(0x3A), RGBU(0x3B),
RGBU(0x3C), RGBU(0x3D), RGBU(0x3E), RGBU(0x3F),
RGBU(0x40), RGBU(0x41), RGBU(0x42), RGBU(0x43),
RGBU(0x44), RGBU(0x45), RGBU(0x46), RGBU(0x47),
RGBU(0x48), RGBU(0x49), RGBU(0x4A), RGBU(0x4B),
RGBU(0x4C), RGBU(0x4D), RGBU(0x4E), RGBU(0x4F),
RGBU(0x50), RGBU(0x51), RGBU(0x52), RGBU(0x53),
RGBU(0x54), RGBU(0x55), RGBU(0x56), RGBU(0x57),
RGBU(0x58), RGBU(0x59), RGBU(0x5A), RGBU(0x5B),
RGBU(0x5C), RGBU(0x5D), RGBU(0x5E), RGBU(0x5F),
RGBU(0x60), RGBU(0x61), RGBU(0x62), RGBU(0x63),
RGBU(0x64), RGBU(0x65), RGBU(0x66), RGBU(0x67),
RGBU(0x68), RGBU(0x69), RGBU(0x6A), RGBU(0x6B),
RGBU(0x6C), RGBU(0x6D), RGBU(0x6E), RGBU(0x6F),
RGBU(0x70), RGBU(0x71), RGBU(0x72), RGBU(0x73),
RGBU(0x74), RGBU(0x75), RGBU(0x76), RGBU(0x77),
RGBU(0x78), RGBU(0x79), RGBU(0x7A), RGBU(0x7B),
RGBU(0x7C), RGBU(0x7D), RGBU(0x7E), RGBU(0x7F),
RGBU(0x80), RGBU(0x81), RGBU(0x82), RGBU(0x83),
RGBU(0x84), RGBU(0x85), RGBU(0x86), RGBU(0x87),
RGBU(0x88), RGBU(0x89), RGBU(0x8A), RGBU(0x8B),
RGBU(0x8C), RGBU(0x8D), RGBU(0x8E), RGBU(0x8F),
RGBU(0x90), RGBU(0x91), RGBU(0x92), RGBU(0x93),
RGBU(0x94), RGBU(0x95), RGBU(0x96), RGBU(0x97),
RGBU(0x98), RGBU(0x99), RGBU(0x9A), RGBU(0x9B),
RGBU(0x9C), RGBU(0x9D), RGBU(0x9E), RGBU(0x9F),
RGBU(0xA0), RGBU(0xA1), RGBU(0xA2), RGBU(0xA3),
RGBU(0xA4), RGBU(0xA5), RGBU(0xA6), RGBU(0xA7),
RGBU(0xA8), RGBU(0xA9), RGBU(0xAA), RGBU(0xAB),
RGBU(0xAC), RGBU(0xAD), RGBU(0xAE), RGBU(0xAF),
RGBU(0xB0), RGBU(0xB1), RGBU(0xB2), RGBU(0xB3),
RGBU(0xB4), RGBU(0xB5), RGBU(0xB6), RGBU(0xB7),
RGBU(0xB8), RGBU(0xB9), RGBU(0xBA), RGBU(0xBB),
RGBU(0xBC), RGBU(0xBD), RGBU(0xBE), RGBU(0xBF),
RGBU(0xC0), RGBU(0xC1), RGBU(0xC2), RGBU(0xC3),
RGBU(0xC4), RGBU(0xC5), RGBU(0xC6), RGBU(0xC7),
RGBU(0xC8), RGBU(0xC9), RGBU(0xCA), RGBU(0xCB),
RGBU(0xCC), RGBU(0xCD), RGBU(0xCE), RGBU(0xCF),
RGBU(0xD0), RGBU(0xD1), RGBU(0xD2), RGBU(0xD3),
RGBU(0xD4), RGBU(0xD5), RGBU(0xD6), RGBU(0xD7),
RGBU(0xD8), RGBU(0xD9), RGBU(0xDA), RGBU(0xDB),
RGBU(0xDC), RGBU(0xDD), RGBU(0xDE), RGBU(0xDF),
RGBU(0xE0), RGBU(0xE1), RGBU(0xE2), RGBU(0xE3),
RGBU(0xE4), RGBU(0xE5), RGBU(0xE6), RGBU(0xE7),
RGBU(0xE8), RGBU(0xE9), RGBU(0xEA), RGBU(0xEB),
RGBU(0xEC), RGBU(0xED), RGBU(0xEE), RGBU(0xEF),
RGBU(0xF0), RGBU(0xF1), RGBU(0xF2), RGBU(0xF3),
RGBU(0xF4), RGBU(0xF5), RGBU(0xF6), RGBU(0xF7),
RGBU(0xF8), RGBU(0xF9), RGBU(0xFA), RGBU(0xFB),
RGBU(0xFC), RGBU(0xFD), RGBU(0xFE), RGBU(0xFF),
// Chroma V table.
RGBV(0x00), RGBV(0x01), RGBV(0x02), RGBV(0x03),
RGBV(0x04), RGBV(0x05), RGBV(0x06), RGBV(0x07),
RGBV(0x08), RGBV(0x09), RGBV(0x0A), RGBV(0x0B),
RGBV(0x0C), RGBV(0x0D), RGBV(0x0E), RGBV(0x0F),
RGBV(0x10), RGBV(0x11), RGBV(0x12), RGBV(0x13),
RGBV(0x14), RGBV(0x15), RGBV(0x16), RGBV(0x17),
RGBV(0x18), RGBV(0x19), RGBV(0x1A), RGBV(0x1B),
RGBV(0x1C), RGBV(0x1D), RGBV(0x1E), RGBV(0x1F),
RGBV(0x20), RGBV(0x21), RGBV(0x22), RGBV(0x23),
RGBV(0x24), RGBV(0x25), RGBV(0x26), RGBV(0x27),
RGBV(0x28), RGBV(0x29), RGBV(0x2A), RGBV(0x2B),
RGBV(0x2C), RGBV(0x2D), RGBV(0x2E), RGBV(0x2F),
RGBV(0x30), RGBV(0x31), RGBV(0x32), RGBV(0x33),
RGBV(0x34), RGBV(0x35), RGBV(0x36), RGBV(0x37),
RGBV(0x38), RGBV(0x39), RGBV(0x3A), RGBV(0x3B),
RGBV(0x3C), RGBV(0x3D), RGBV(0x3E), RGBV(0x3F),
RGBV(0x40), RGBV(0x41), RGBV(0x42), RGBV(0x43),
RGBV(0x44), RGBV(0x45), RGBV(0x46), RGBV(0x47),
RGBV(0x48), RGBV(0x49), RGBV(0x4A), RGBV(0x4B),
RGBV(0x4C), RGBV(0x4D), RGBV(0x4E), RGBV(0x4F),
RGBV(0x50), RGBV(0x51), RGBV(0x52), RGBV(0x53),
RGBV(0x54), RGBV(0x55), RGBV(0x56), RGBV(0x57),
RGBV(0x58), RGBV(0x59), RGBV(0x5A), RGBV(0x5B),
RGBV(0x5C), RGBV(0x5D), RGBV(0x5E), RGBV(0x5F),
RGBV(0x60), RGBV(0x61), RGBV(0x62), RGBV(0x63),
RGBV(0x64), RGBV(0x65), RGBV(0x66), RGBV(0x67),
RGBV(0x68), RGBV(0x69), RGBV(0x6A), RGBV(0x6B),
RGBV(0x6C), RGBV(0x6D), RGBV(0x6E), RGBV(0x6F),
RGBV(0x70), RGBV(0x71), RGBV(0x72), RGBV(0x73),
RGBV(0x74), RGBV(0x75), RGBV(0x76), RGBV(0x77),
RGBV(0x78), RGBV(0x79), RGBV(0x7A), RGBV(0x7B),
RGBV(0x7C), RGBV(0x7D), RGBV(0x7E), RGBV(0x7F),
RGBV(0x80), RGBV(0x81), RGBV(0x82), RGBV(0x83),
RGBV(0x84), RGBV(0x85), RGBV(0x86), RGBV(0x87),
RGBV(0x88), RGBV(0x89), RGBV(0x8A), RGBV(0x8B),
RGBV(0x8C), RGBV(0x8D), RGBV(0x8E), RGBV(0x8F),
RGBV(0x90), RGBV(0x91), RGBV(0x92), RGBV(0x93),
RGBV(0x94), RGBV(0x95), RGBV(0x96), RGBV(0x97),
RGBV(0x98), RGBV(0x99), RGBV(0x9A), RGBV(0x9B),
RGBV(0x9C), RGBV(0x9D), RGBV(0x9E), RGBV(0x9F),
RGBV(0xA0), RGBV(0xA1), RGBV(0xA2), RGBV(0xA3),
RGBV(0xA4), RGBV(0xA5), RGBV(0xA6), RGBV(0xA7),
RGBV(0xA8), RGBV(0xA9), RGBV(0xAA), RGBV(0xAB),
RGBV(0xAC), RGBV(0xAD), RGBV(0xAE), RGBV(0xAF),
RGBV(0xB0), RGBV(0xB1), RGBV(0xB2), RGBV(0xB3),
RGBV(0xB4), RGBV(0xB5), RGBV(0xB6), RGBV(0xB7),
RGBV(0xB8), RGBV(0xB9), RGBV(0xBA), RGBV(0xBB),
RGBV(0xBC), RGBV(0xBD), RGBV(0xBE), RGBV(0xBF),
RGBV(0xC0), RGBV(0xC1), RGBV(0xC2), RGBV(0xC3),
RGBV(0xC4), RGBV(0xC5), RGBV(0xC6), RGBV(0xC7),
RGBV(0xC8), RGBV(0xC9), RGBV(0xCA), RGBV(0xCB),
RGBV(0xCC), RGBV(0xCD), RGBV(0xCE), RGBV(0xCF),
RGBV(0xD0), RGBV(0xD1), RGBV(0xD2), RGBV(0xD3),
RGBV(0xD4), RGBV(0xD5), RGBV(0xD6), RGBV(0xD7),
RGBV(0xD8), RGBV(0xD9), RGBV(0xDA), RGBV(0xDB),
RGBV(0xDC), RGBV(0xDD), RGBV(0xDE), RGBV(0xDF),
RGBV(0xE0), RGBV(0xE1), RGBV(0xE2), RGBV(0xE3),
RGBV(0xE4), RGBV(0xE5), RGBV(0xE6), RGBV(0xE7),
RGBV(0xE8), RGBV(0xE9), RGBV(0xEA), RGBV(0xEB),
RGBV(0xEC), RGBV(0xED), RGBV(0xEE), RGBV(0xEF),
RGBV(0xF0), RGBV(0xF1), RGBV(0xF2), RGBV(0xF3),
RGBV(0xF4), RGBV(0xF5), RGBV(0xF6), RGBV(0xF7),
RGBV(0xF8), RGBV(0xF9), RGBV(0xFA), RGBV(0xFB),
RGBV(0xFC), RGBV(0xFD), RGBV(0xFE), RGBV(0xFF),
};
#undef RGBY #undef RGBY
#undef RGBU #undef RGBU
#undef RGBV #undef RGBV
// ABGR table
#define RGBY(i) { \
static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
static_cast<int16>(1.164 * 64 * (i - 16) + 0.5), \
static_cast<int16>(256 * 64 - 1) \
}
#define RGBU(i) { \
0, \
static_cast<int16>(-0.391 * 64 * (i - 128) + 0.5), \
static_cast<int16>(2.018 * 64 * (i - 128) + 0.5), \
0 \
}
#define RGBV(i) { \
static_cast<int16>(1.596 * 64 * (i - 128) + 0.5), \
static_cast<int16>(-0.813 * 64 * (i - 128) + 0.5), \
0, \
0 \
}
#ifdef OSX
MAKETABLE(kCoefficientsAbgrY)
#else
MAKETABLE(_kCoefficientsAbgrY)
#endif
} // extern "C" } // extern "C"
...@@ -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