1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef MEDIA_BASE_YUV_CONVERT_H_
6#define MEDIA_BASE_YUV_CONVERT_H_
7
8#include "base/basictypes.h"
9#include "media/base/media_export.h"
10#include "media/base/simd/yuv_to_rgb_table.h"
11
12// Visual Studio 2010 does not support MMX intrinsics on x64.
13// Some win64 yuv_convert code paths use SSE+MMX yasm, so without rewriting
14// them, we use yasm EmptyRegisterState_MMX in place of _mm_empty() or
15// hide the versions implemented with heavy use of MMX intrinsics.
16// TODO(wolenetz): Use MMX intrinsics when compiling win64 with Visual
17// Studio 2012? http://crbug.com/173450
18#if defined(ARCH_CPU_X86_FAMILY) && \
19    !(defined(ARCH_CPU_X86_64) && defined(COMPILER_MSVC))
20#define MEDIA_MMX_INTRINSICS_AVAILABLE
21#endif
22
23namespace media {
24
25// Type of YUV surface.
26enum YUVType {
27  YV16  = 0,  // YV16 is half width and full height chroma channels.
28  YV12  = 1,  // YV12 is half width and half height chroma channels.
29  YV12J = 2,  // YV12J is the same as YV12, but in JPEG color range.
30};
31
32// Get the appropriate value to bitshift by for vertical indices.
33MEDIA_EXPORT int GetVerticalShift(YUVType type);
34
35// Get the appropriate lookup table for a given YUV format.
36MEDIA_EXPORT const int16 (&GetLookupTable(YUVType type))[1024][4];
37
38// Mirror means flip the image horizontally, as in looking in a mirror.
39// Rotate happens after mirroring.
40enum Rotate {
41  ROTATE_0,           // Rotation off.
42  ROTATE_90,          // Rotate clockwise.
43  ROTATE_180,         // Rotate upside down.
44  ROTATE_270,         // Rotate counter clockwise.
45  MIRROR_ROTATE_0,    // Mirror horizontally.
46  MIRROR_ROTATE_90,   // Mirror then Rotate clockwise.
47  MIRROR_ROTATE_180,  // Mirror vertically.
48  MIRROR_ROTATE_270,  // Transpose.
49};
50
51// Filter affects how scaling looks.
52enum ScaleFilter {
53  FILTER_NONE = 0,        // No filter (point sampled).
54  FILTER_BILINEAR_H = 1,  // Bilinear horizontal filter.
55  FILTER_BILINEAR_V = 2,  // Bilinear vertical filter.
56  FILTER_BILINEAR = 3,    // Bilinear filter.
57};
58
59MEDIA_EXPORT void InitializeCPUSpecificYUVConversions();
60
61// Convert a frame of YUV to 32 bit ARGB.
62// Pass in YV16/YV12 depending on source format
63MEDIA_EXPORT void ConvertYUVToRGB32(const uint8* yplane,
64                                    const uint8* uplane,
65                                    const uint8* vplane,
66                                    uint8* rgbframe,
67                                    int width,
68                                    int height,
69                                    int ystride,
70                                    int uvstride,
71                                    int rgbstride,
72                                    YUVType yuv_type);
73
74// Convert a frame of YUVA to 32 bit ARGB.
75// Pass in YV12A
76MEDIA_EXPORT void ConvertYUVAToARGB(const uint8* yplane,
77                                    const uint8* uplane,
78                                    const uint8* vplane,
79                                    const uint8* aplane,
80                                    uint8* rgbframe,
81                                    int width,
82                                    int height,
83                                    int ystride,
84                                    int uvstride,
85                                    int astride,
86                                    int rgbstride,
87                                    YUVType yuv_type);
88
89// Scale a frame of YUV to 32 bit ARGB.
90// Supports rotation and mirroring.
91MEDIA_EXPORT void ScaleYUVToRGB32(const uint8* yplane,
92                                  const uint8* uplane,
93                                  const uint8* vplane,
94                                  uint8* rgbframe,
95                                  int source_width,
96                                  int source_height,
97                                  int width,
98                                  int height,
99                                  int ystride,
100                                  int uvstride,
101                                  int rgbstride,
102                                  YUVType yuv_type,
103                                  Rotate view_rotate,
104                                  ScaleFilter filter);
105
106// Biliner Scale a frame of YV12 to 32 bits ARGB on a specified rectangle.
107// |yplane|, etc and |rgbframe| should point to the top-left pixels of the
108// source and destination buffers.
109MEDIA_EXPORT void ScaleYUVToRGB32WithRect(const uint8* yplane,
110                                          const uint8* uplane,
111                                          const uint8* vplane,
112                                          uint8* rgbframe,
113                                          int source_width,
114                                          int source_height,
115                                          int dest_width,
116                                          int dest_height,
117                                          int dest_rect_left,
118                                          int dest_rect_top,
119                                          int dest_rect_right,
120                                          int dest_rect_bottom,
121                                          int ystride,
122                                          int uvstride,
123                                          int rgbstride);
124
125MEDIA_EXPORT void ConvertRGB32ToYUV(const uint8* rgbframe,
126                                    uint8* yplane,
127                                    uint8* uplane,
128                                    uint8* vplane,
129                                    int width,
130                                    int height,
131                                    int rgbstride,
132                                    int ystride,
133                                    int uvstride);
134
135MEDIA_EXPORT void ConvertRGB24ToYUV(const uint8* rgbframe,
136                                    uint8* yplane,
137                                    uint8* uplane,
138                                    uint8* vplane,
139                                    int width,
140                                    int height,
141                                    int rgbstride,
142                                    int ystride,
143                                    int uvstride);
144
145MEDIA_EXPORT void ConvertYUY2ToYUV(const uint8* src,
146                                   uint8* yplane,
147                                   uint8* uplane,
148                                   uint8* vplane,
149                                   int width,
150                                   int height);
151
152MEDIA_EXPORT void ConvertNV21ToYUV(const uint8* src,
153                                   uint8* yplane,
154                                   uint8* uplane,
155                                   uint8* vplane,
156                                   int width,
157                                   int height);
158
159// Empty SIMD register state after calling optimized scaler functions.
160MEDIA_EXPORT void EmptyRegisterState();
161
162}  // namespace media
163
164#endif  // MEDIA_BASE_YUV_CONVERT_H_
165