diff options
author | fbarchard@chromium.org <fbarchard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-11 22:19:41 +0000 |
---|---|---|
committer | fbarchard@chromium.org <fbarchard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-11 22:19:41 +0000 |
commit | ce7a1c1b77b669d7c146a2459d731e7d0452671c (patch) | |
tree | cb8bd3a6acd91067fe4f2617ed9ff477b077d7aa /media/base | |
parent | 1d3aa17b318b5691cf5b292ba6336f25f9d25d3c (diff) | |
download | chromium_src-ce7a1c1b77b669d7c146a2459d731e7d0452671c.zip chromium_src-ce7a1c1b77b669d7c146a2459d731e7d0452671c.tar.gz chromium_src-ce7a1c1b77b669d7c146a2459d731e7d0452671c.tar.bz2 |
Review URL: http://codereview.chromium.org/115197
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15800 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/base')
-rw-r--r-- | media/base/yuv_scale.cc | 120 | ||||
-rw-r--r-- | media/base/yuv_scale.h | 48 | ||||
-rw-r--r-- | media/base/yuv_scale_unittest.cc | 6 |
3 files changed, 134 insertions, 40 deletions
diff --git a/media/base/yuv_scale.cc b/media/base/yuv_scale.cc index 7f39861..96e905c 100644 --- a/media/base/yuv_scale.cc +++ b/media/base/yuv_scale.cc @@ -20,36 +20,78 @@ static void ScaleYV12ToRGB32Row(const uint8* y_buf, const uint8* u_buf, const uint8* v_buf, uint8* rgb_buf, - size_t width, - size_t scaled_width); + int width, + int scaled_width); static void HalfYV12ToRGB32Row(const uint8* y_buf, const uint8* u_buf, const uint8* v_buf, uint8* rgb_buf, - size_t width); + int width); + +// TODO(fbarchard): Refactor row functions into seperate module and test on Mac. +#ifdef _MSC_VER +extern "C" void ConvertYV12ToRGB32Row(const uint8* y_buf, + const uint8* u_buf, + const uint8* v_buf, + uint8* rgb_buf, + size_t width); +#endif // Scale a frame of YV12 (aka YUV420) to 32 bit ARGB. void ScaleYV12ToRGB32(const uint8* y_buf, const uint8* u_buf, const uint8* v_buf, uint8* rgb_buf, - size_t width, - size_t height, - size_t scaled_width, - size_t scaled_height, + int width, + int height, + int scaled_width, + int scaled_height, int y_pitch, int uv_pitch, - int rgb_pitch) { + int rgb_pitch, + Rotate view_rotate) { + // Rotations that start at right side of image. + if ((view_rotate == ROTATE_180) || + (view_rotate == ROTATE_270) || + (view_rotate == MIRROR_ROTATE_0) || + (view_rotate == MIRROR_ROTATE_90)) { + y_buf += width - 1; + u_buf += width / 2 - 1; + v_buf += width / 2 - 1; + width = -width; + } + // Rotations that start at bottom of image. + if ((view_rotate == ROTATE_90) || + (view_rotate == ROTATE_180) || + (view_rotate == MIRROR_ROTATE_90) || + (view_rotate == MIRROR_ROTATE_180)) { + y_buf += (height - 1) * y_pitch; + u_buf += (height / 2 - 1) * uv_pitch; + v_buf += (height / 2 - 1) * uv_pitch; + height = -height; + } + // Only these rotations are implemented. + DCHECK((view_rotate == ROTATE_0) || + (view_rotate == ROTATE_180) || + (view_rotate == MIRROR_ROTATE_0) || + (view_rotate == MIRROR_ROTATE_180)); + #ifdef _OPENMP #pragma omp parallel for #endif - for (int y = 0; y < static_cast<int>(scaled_height); ++y) { + for (int y = 0; y < scaled_height; ++y) { uint8* dest_pixel = rgb_buf + y * rgb_pitch; int scaled_y = (y * height / scaled_height); + const uint8* y_ptr = y_buf + scaled_y * y_pitch; const uint8* u_ptr = u_buf + scaled_y / 2 * uv_pitch; const uint8* v_ptr = v_buf + scaled_y / 2 * uv_pitch; - +#ifdef _MSC_VER + if (scaled_width == width) { + ConvertYV12ToRGB32Row(y_ptr, u_ptr, v_ptr, + dest_pixel, scaled_width); + } else +#endif if (scaled_width == (width / 2)) { HalfYV12ToRGB32Row(y_ptr, u_ptr, v_ptr, dest_pixel, scaled_width); @@ -65,17 +107,43 @@ void ScaleYV16ToRGB32(const uint8* y_buf, const uint8* u_buf, const uint8* v_buf, uint8* rgb_buf, - size_t width, - size_t height, - size_t scaled_width, - size_t scaled_height, + int width, + int height, + int scaled_width, + int scaled_height, int y_pitch, int uv_pitch, - int rgb_pitch) { + int rgb_pitch, + Rotate view_rotate) { + // Rotations that start at right side of image. + if ((view_rotate == ROTATE_180) || + (view_rotate == ROTATE_270) || + (view_rotate == MIRROR_ROTATE_0) || + (view_rotate == MIRROR_ROTATE_90)) { + y_buf += width - 1; + u_buf += width / 2 - 1; + v_buf += width / 2 - 1; + width = -width; + } + // Rotations that start at bottom of image. + if ((view_rotate == ROTATE_90) || + (view_rotate == ROTATE_180) || + (view_rotate == MIRROR_ROTATE_90) || + (view_rotate == MIRROR_ROTATE_180)) { + y_buf += (height - 1) * y_pitch; + u_buf += (height - 1) * uv_pitch; + v_buf += (height - 1) * uv_pitch; + height = -height; + } + // Only these rotations are implemented. + DCHECK((view_rotate == ROTATE_0) || + (view_rotate == ROTATE_180) || + (view_rotate == MIRROR_ROTATE_0) || + (view_rotate == MIRROR_ROTATE_180)); #ifdef _OPENMP #pragma omp parallel for #endif - for (int y = 0; y < static_cast<int>(scaled_height); ++y) { + for (int y = 0; y < scaled_height; ++y) { uint8* dest_pixel = rgb_buf + y * rgb_pitch; int scaled_y = (y * height / scaled_height); const uint8* y_ptr = y_buf + scaled_y * y_pitch; @@ -100,7 +168,7 @@ static uint8 g_rgb_clip_table[kClipOverflow + kClipTableSize + kClipOverflow] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 128 underflow values - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // cliped to 0. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // clipped to 0. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -148,7 +216,7 @@ static uint8 g_rgb_clip_table[kClipOverflow 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 128 overflow values - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // cliped to 255. + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // clipped to 255. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, @@ -171,9 +239,9 @@ static uint8 g_rgb_clip_table[kClipOverflow // Therefore source range is -128 to 384. // Output clips to unsigned 0 to 255. static inline uint32 clip(int32 value) { - DCHECK(((value >> 8) + kClipOverflow) >= 0); - DCHECK(((value >> 8) + kClipOverflow) < - (kClipOverflow + kClipTableSize + kClipOverflow)); +// DCHECK(((value >> 8) + kClipOverflow) >= 0); +// DCHECK(((value >> 8) + kClipOverflow) < +// (kClipOverflow + kClipTableSize + kClipOverflow)); return static_cast<uint32>(g_rgb_clip_table[((value) >> 8) + kClipOverflow]); } @@ -186,11 +254,11 @@ static void ScaleYV12ToRGB32Row(const uint8* y_buf, const uint8* u_buf, const uint8* v_buf, uint8* rgb_buf, - size_t width, - size_t scaled_width) { + int width, + int scaled_width) { int scaled_dx = width * 16 / scaled_width; int scaled_x = 0; - for (int32 x = 0; x < static_cast<int32>(scaled_width); ++x) { + for (int32 x = 0; x < scaled_width; ++x) { uint8 u = u_buf[scaled_x >> 5]; uint8 v = v_buf[scaled_x >> 5]; int32 d = static_cast<int32>(u) - 128; @@ -233,8 +301,8 @@ static void HalfYV12ToRGB32Row(const uint8* y_buf, const uint8* u_buf, const uint8* v_buf, uint8* rgb_buf, - size_t width) { - for (int32 x = 0; x < static_cast<int32>(width); ++x) { + int width) { + for (int32 x = 0; x < width; ++x) { uint8 u = u_buf[x]; uint8 v = v_buf[x]; int32 d = static_cast<int32>(u) - 128; diff --git a/media/base/yuv_scale.h b/media/base/yuv_scale.h index f354942..a029664 100644 --- a/media/base/yuv_scale.h +++ b/media/base/yuv_scale.h @@ -9,33 +9,57 @@ namespace media { +// Mirror means flip the image horizontally, as in looking in a mirror. +// Rotate happens after mirroring. + +enum Rotate { + ROTATE_0, // Rotation off. + ROTATE_90, // Rotate clockwise. + ROTATE_180, // Rotate upside down. + ROTATE_270, // Rotate counter clockwise. + MIRROR_ROTATE_0, // Mirror horizontally. + MIRROR_ROTATE_90, // Mirror then Rotate clockwise. + MIRROR_ROTATE_180, // Mirror vertically. + MIRROR_ROTATE_270, // Transpose. +}; + +// Diagram showing origin and direction of source sampling. +// ->0 4<- +// 7 3 +// +// 6 5 +// ->1 2<- + + // Scale a frame of YV12 (aka YUV420) to 32 bit ARGB. void ScaleYV12ToRGB32(const uint8* yplane, const uint8* uplane, const uint8* vplane, uint8* rgbframe, - size_t frame_width, - size_t frame_height, - size_t scaled_width, - size_t scaled_height, + int frame_width, + int frame_height, + int scaled_width, + int scaled_height, int ystride, int uvstride, - int rgbstride); + int rgbstride, + Rotate view_rotate); // Scale a frame of YV16 (aka YUV422) to 32 bit ARGB. void ScaleYV16ToRGB32(const uint8* yplane, const uint8* uplane, const uint8* vplane, uint8* rgbframe, - size_t frame_width, - size_t frame_height, - size_t scaled_width, - size_t scaled_height, + int frame_width, + int frame_height, + int scaled_width, + int scaled_height, int ystride, int uvstride, - int rgbstride); - -#endif // MEDIA_BASE_YUV_SCALE_H_ + int rgbstride, + Rotate view_rotate); } // namespace media +#endif // MEDIA_BASE_YUV_SCALE_H_ + diff --git a/media/base/yuv_scale_unittest.cc b/media/base/yuv_scale_unittest.cc index f5e2f0d..c81c74f 100644 --- a/media/base/yuv_scale_unittest.cc +++ b/media/base/yuv_scale_unittest.cc @@ -68,7 +68,8 @@ TEST(YuvScaleTest, Basic) { kScaledWidth, kScaledHeight, // Dimensions kWidth, // YStride kWidth / 2, // UvStride - kScaledWidth * kBpp); // RgbStride + kScaledWidth * kBpp, // RgbStride + media::ROTATE_0); unsigned int rgb_hash = hash(rgb_scaled_bytes, size_of_rgb_scaled); @@ -106,7 +107,8 @@ TEST(YV16ScaleTest, Basic) { kScaledWidth, kScaledHeight, // Dimensions kWidth, // YStride kWidth / 2, // UvStride - kScaledWidth * kBpp); // RgbStride + kScaledWidth * kBpp, // RgbStride + media::ROTATE_0); unsigned int rgb_hash = hash(rgb_scaled_bytes, size_of_rgb_scaled); |