@@ -66,14 +66,20 @@ namespace
66
66
{
67
67
__constant__ float constHueColorSpaceMat[9 ] = {1 .1644f , 0 .0f , 1 .596f , 1 .1644f , -0 .3918f , -0 .813f , 1 .1644f , 2 .0172f , 0 .0f };
68
68
69
+ template <bool fullRange>
69
70
__device__ static void YUV2RGB (const uint* yuvi, float * red, float * green, float * blue)
70
71
{
71
72
float luma, chromaCb, chromaCr;
72
-
73
- // Prepare for hue adjustment
74
- luma = (float )yuvi[0 ];
75
- chromaCb = (float )((int )yuvi[1 ] - 512 .0f );
76
- chromaCr = (float )((int )yuvi[2 ] - 512 .0f );
73
+ if (fullRange) {
74
+ luma = (float )(((int )yuvi[0 ] * 219 .0f / 255 .0f ));
75
+ chromaCb = (float )(((int )yuvi[1 ] - 512 .0f ) * 224 .0f / 255 .0f );
76
+ chromaCr = (float )(((int )yuvi[2 ] - 512 .0f ) * 224 .0f / 255 .0f );
77
+ }
78
+ else {
79
+ luma = (float )((int )yuvi[0 ] - 64 .0f );
80
+ chromaCb = (float )((int )yuvi[1 ] - 512 .0f );
81
+ chromaCr = (float )((int )yuvi[2 ] - 512 .0f );
82
+ }
77
83
78
84
// Convert YUV To RGB with hue adjustment
79
85
*red = (luma * constHueColorSpaceMat[0 ]) +
@@ -112,6 +118,7 @@ namespace
112
118
#define COLOR_COMPONENT_BIT_SIZE 10
113
119
#define COLOR_COMPONENT_MASK 0x3FF
114
120
121
+ template <bool fullRange>
115
122
__global__ void NV12_to_BGRA (const uchar* srcImage, size_t nSourcePitch,
116
123
uint* dstImage, size_t nDestPitch,
117
124
uint width, uint height)
@@ -135,31 +142,11 @@ namespace
135
142
136
143
const int y_chroma = y >> 1 ;
137
144
138
- if (y & 1 ) // odd scanline ?
139
- {
140
- uint chromaCb = srcImage[chromaOffset + y_chroma * nSourcePitch + x ];
141
- uint chromaCr = srcImage[chromaOffset + y_chroma * nSourcePitch + x + 1 ];
142
-
143
- if (y_chroma < ((height >> 1 ) - 1 )) // interpolate chroma vertically
144
- {
145
- chromaCb = (chromaCb + srcImage[chromaOffset + (y_chroma + 1 ) * nSourcePitch + x ] + 1 ) >> 1 ;
146
- chromaCr = (chromaCr + srcImage[chromaOffset + (y_chroma + 1 ) * nSourcePitch + x + 1 ] + 1 ) >> 1 ;
147
- }
145
+ yuv101010Pel[0 ] |= ((uint)srcImage[chromaOffset + y_chroma * nSourcePitch + x ] << ( COLOR_COMPONENT_BIT_SIZE + 2 ));
146
+ yuv101010Pel[0 ] |= ((uint)srcImage[chromaOffset + y_chroma * nSourcePitch + x + 1 ] << ((COLOR_COMPONENT_BIT_SIZE << 1 ) + 2 ));
148
147
149
- yuv101010Pel[0 ] |= (chromaCb << ( COLOR_COMPONENT_BIT_SIZE + 2 ));
150
- yuv101010Pel[0 ] |= (chromaCr << ((COLOR_COMPONENT_BIT_SIZE << 1 ) + 2 ));
151
-
152
- yuv101010Pel[1 ] |= (chromaCb << ( COLOR_COMPONENT_BIT_SIZE + 2 ));
153
- yuv101010Pel[1 ] |= (chromaCr << ((COLOR_COMPONENT_BIT_SIZE << 1 ) + 2 ));
154
- }
155
- else
156
- {
157
- yuv101010Pel[0 ] |= ((uint)srcImage[chromaOffset + y_chroma * nSourcePitch + x ] << ( COLOR_COMPONENT_BIT_SIZE + 2 ));
158
- yuv101010Pel[0 ] |= ((uint)srcImage[chromaOffset + y_chroma * nSourcePitch + x + 1 ] << ((COLOR_COMPONENT_BIT_SIZE << 1 ) + 2 ));
159
-
160
- yuv101010Pel[1 ] |= ((uint)srcImage[chromaOffset + y_chroma * nSourcePitch + x ] << ( COLOR_COMPONENT_BIT_SIZE + 2 ));
161
- yuv101010Pel[1 ] |= ((uint)srcImage[chromaOffset + y_chroma * nSourcePitch + x + 1 ] << ((COLOR_COMPONENT_BIT_SIZE << 1 ) + 2 ));
162
- }
148
+ yuv101010Pel[1 ] |= ((uint)srcImage[chromaOffset + y_chroma * nSourcePitch + x ] << ( COLOR_COMPONENT_BIT_SIZE + 2 ));
149
+ yuv101010Pel[1 ] |= ((uint)srcImage[chromaOffset + y_chroma * nSourcePitch + x + 1 ] << ((COLOR_COMPONENT_BIT_SIZE << 1 ) + 2 ));
163
150
164
151
// this steps performs the color conversion
165
152
uint yuvi[6 ];
@@ -174,8 +161,8 @@ namespace
174
161
yuvi[5 ] = ((yuv101010Pel[1 ] >> (COLOR_COMPONENT_BIT_SIZE << 1 )) & COLOR_COMPONENT_MASK);
175
162
176
163
// YUV to RGB Transformation conversion
177
- YUV2RGB (&yuvi[0 ], &red[0 ], &green[0 ], &blue[0 ]);
178
- YUV2RGB (&yuvi[3 ], &red[1 ], &green[1 ], &blue[1 ]);
164
+ YUV2RGB<fullRange> (&yuvi[0 ], &red[0 ], &green[0 ], &blue[0 ]);
165
+ YUV2RGB<fullRange> (&yuvi[3 ], &red[1 ], &green[1 ], &blue[1 ]);
179
166
180
167
// Clamp the results to RGBA
181
168
@@ -186,13 +173,15 @@ namespace
186
173
}
187
174
}
188
175
189
- void nv12ToBgra (const GpuMat& decodedFrame, GpuMat& outFrame, int width, int height, cudaStream_t stream)
176
+ void nv12ToBgra (const GpuMat& decodedFrame, GpuMat& outFrame, int width, int height, const bool videoFullRangeFlag, cudaStream_t stream)
190
177
{
191
178
outFrame.create (height, width, CV_8UC4);
192
179
dim3 block (32 , 8 );
193
180
dim3 grid (divUp (width, 2 * block.x ), divUp (height, block.y ));
194
- NV12_to_BGRA<< <grid, block, 0 , stream >> > (decodedFrame.ptr <uchar>(), decodedFrame.step ,
195
- outFrame.ptr <uint>(), outFrame.step , width, height);
181
+ if (videoFullRangeFlag)
182
+ NV12_to_BGRA<true > << <grid, block, 0 , stream >> > (decodedFrame.ptr <uchar>(), decodedFrame.step , outFrame.ptr <uint>(), outFrame.step , width, height);
183
+ else
184
+ NV12_to_BGRA<false > << <grid, block, 0 , stream >> > (decodedFrame.ptr <uchar>(), decodedFrame.step , outFrame.ptr <uint>(), outFrame.step , width, height);
196
185
CV_CUDEV_SAFE_CALL (cudaGetLastError ());
197
186
if (stream == 0 )
198
187
CV_CUDEV_SAFE_CALL (cudaDeviceSynchronize ());
0 commit comments