xref: /haiku/src/add-ons/media/plugins/ffmpeg/gfx_util.cpp (revision 56187df6ebd9d1fb16bf954fce8df0999e9e3048)
1 #include "gfx_util.h"
2 
3 #include <strings.h>
4 #include <stdio.h>
5 
6 #include "CpuCapabilities.h"
7 #include "gfx_conv_c.h"
8 #include "gfx_conv_mmx.h"
9 
10 
11 // ref docs
12 // http://www.joemaller.com/fcp/fxscript_yuv_color.shtml
13 
14 
15 #if 1
16   #define TRACE(a...) printf(a)
17 #else
18   #define TRACE(a...)
19 #endif
20 
21 
22 //! This function will try to find the best colorspaces for both the ff-codec
23 // and the Media Kit sides.
24 gfx_convert_func
25 resolve_colorspace(color_space colorSpace, PixelFormat pixelFormat, int width,
26 	int height)
27 {
28 	CPUCapabilities cpu;
29 
30 	switch (colorSpace) {
31 		case B_RGB32:
32 			if (pixelFormat == PIX_FMT_YUV410P) {
33 				TRACE("resolve_colorspace: gfx_conv_yuv410p_rgb32_c\n");
34 				return gfx_conv_yuv410p_rgb32_c;
35 			}
36 
37 			if (pixelFormat == PIX_FMT_YUV411P) {
38 				TRACE("resolve_colorspace: gfx_conv_yuv411p_rgb32_c\n");
39 				return gfx_conv_yuv411p_rgb32_c;
40 			}
41 
42 			if (pixelFormat == PIX_FMT_YUV420P
43 				|| pixelFormat == PIX_FMT_YUVJ420P) {
44 				if (cpu.HasSSE2() && width % 8 == 0 && height % 2 == 0) {
45 					TRACE("resolve_colorspace: "
46 						"gfx_conv_yuv420p_rgba32_sse2\n");
47 					return gfx_conv_yuv420p_rgba32_sse2;
48 				} else if (cpu.HasSSE1() && width % 4 == 0
49 					&& height % 2 == 0) {
50 					TRACE("resolve_colorspace: gfx_conv_yuv420p_rgba32_sse\n");
51 					return gfx_conv_yuv420p_rgba32_sse;
52 				} else {
53 					TRACE("resolve_colorspace: gfx_conv_YCbCr420p_RGB32_c\n");
54 					return gfx_conv_YCbCr420p_RGB32_c;
55 				}
56 			}
57 
58 			if (pixelFormat == PIX_FMT_YUV422P
59 				|| pixelFormat == PIX_FMT_YUVJ422P) {
60 				if (cpu.HasSSE2() && width % 8 == 0)
61 					return gfx_conv_yuv422p_rgba32_sse2;
62 				else if (cpu.HasSSE1() && width % 4 == 0)
63 					return gfx_conv_yuv422p_rgba32_sse;
64 				else
65 					return gfx_conv_YCbCr422_RGB32_c;
66 			}
67 
68 			TRACE("resolve_colorspace: %s => B_RGB32: NULL\n",
69 				pixfmt_to_string(pixelFormat));
70 			return NULL;
71 
72 		case B_RGB24_BIG:
73 			TRACE("resolve_colorspace: %s => B_RGB24_BIG: NULL\n",
74 				pixfmt_to_string(pixelFormat));
75 			return NULL;
76 
77 		case B_RGB24:
78 			TRACE("resolve_colorspace: %s => B_RGB24: NULL\n",
79 				pixfmt_to_string(pixelFormat));
80 			return NULL;
81 
82 		case B_YCbCr422:
83 			if (pixelFormat == PIX_FMT_YUV410P) {
84 				TRACE("resolve_colorspace: gfx_conv_yuv410p_ycbcr422_c\n");
85 				return gfx_conv_yuv410p_ycbcr422_c;
86 			}
87 
88 			if (pixelFormat == PIX_FMT_YUV411P) {
89 				TRACE("resolve_colorspace: gfx_conv_yuv411p_ycbcr422_c\n");
90 				return gfx_conv_yuv411p_ycbcr422_c;
91 			}
92 
93 			if (pixelFormat == PIX_FMT_YUV420P
94 				|| pixelFormat == PIX_FMT_YUVJ420P) {
95 				TRACE("resolve_colorspace: gfx_conv_yuv420p_ycbcr422_c\n");
96 				return gfx_conv_yuv420p_ycbcr422_c;
97 			}
98 
99 			if (pixelFormat == PIX_FMT_YUYV422) {
100 				TRACE("resolve_colorspace: PIX_FMT_YUV422 => B_YCbCr422: "
101 					"gfx_conv_null\n");
102 				return gfx_conv_null;
103 			}
104 
105 			TRACE("resolve_colorspace: %s => B_YCbCr422: NULL\n",
106 				pixfmt_to_string(pixelFormat));
107 			return NULL;
108 
109 		default:
110 			TRACE("resolve_colorspace: default: NULL!!!\n");
111 			return NULL;
112 	}
113 }
114 
115 
116 const char*
117 pixfmt_to_string(int pixFormat)
118 {
119 	switch (pixFormat) {
120 		case PIX_FMT_NONE:
121 			return "PIX_FMT_NONE";
122 
123 		case PIX_FMT_YUV420P:
124 			// planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
125 			return "PIX_FMT_YUV420P";
126 
127 		case PIX_FMT_YUYV422:
128 			// packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
129 			return "PIX_FMT_YUYV422";
130 
131 		case PIX_FMT_RGB24:
132 			// packed RGB 8:8:8, 24bpp, RGBRGB...
133 			return "PIX_FMT_RGB24";
134 
135 		case PIX_FMT_BGR24:
136 			// packed RGB 8:8:8, 24bpp, BGRBGR...
137 			return "PIX_FMT_BGR24";
138 
139 		case PIX_FMT_YUV422P:
140 			// planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
141 			return "PIX_FMT_YUV422P";
142 
143 		case PIX_FMT_YUV444P:
144 			// planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
145 			return "PIX_FMT_YUV444P";
146 
147 		case PIX_FMT_RGB32:
148 			// packed RGB 8:8:8, 32bpp, (msb)8A 8R 8G 8B(lsb), in CPU
149 			// endianness
150 			return "PIX_FMT_RGB32";
151 
152 		case PIX_FMT_YUV410P:
153 			// planar YUV 4:1:0,  9bpp, (1 Cr & Cb sample per 4x4 Y samples)
154 			return "PIX_FMT_YUV410P";
155 
156 		case PIX_FMT_YUV411P:
157 			// planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
158 			return "PIX_FMT_YUV411P";
159 
160 		case PIX_FMT_RGB565:
161 			// packed RGB 5:6:5, 16bpp, (msb)5R 6G 5B(lsb), in CPU endianness
162 			return "PIX_FMT_RGB565";
163 
164 		case PIX_FMT_RGB555:
165 			// packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), in CPU
166 			// endianness, most significant bit to 0
167 			return "PIX_FMT_RGB555";
168 
169 		case PIX_FMT_GRAY8:
170 			// Y, 8bpp
171 			return "PIX_FMT_GRAY8";
172 
173 		case PIX_FMT_MONOWHITE:
174 			// Y, 1bpp, 0 is white, 1 is black
175 			return "PIX_FMT_MONOWHITE";
176 
177 		case PIX_FMT_MONOBLACK:
178 			// Y, 1bpp, 0 is black, 1 is white
179 			return "PIX_FMT_MONOBLACK";
180 
181 		case PIX_FMT_PAL8:
182 			// 8 bit with PIX_FMT_RGB32 palette
183 			return "PIX_FMT_PAL8";
184 
185 		case PIX_FMT_YUVJ420P:
186 			// planar YUV 4:2:0, 12bpp, full scale (JPEG)
187 			return "PIX_FMT_YUVJ420P - YUV420P (Jpeg)";
188 
189 		case PIX_FMT_YUVJ422P:
190 			// planar YUV 4:2:2, 16bpp, full scale (JPEG)
191 			return "PIX_FMT_YUVJ422P - YUV422P (Jpeg)";
192 
193 		case PIX_FMT_YUVJ444P:
194 			// planar YUV 4:4:4, 24bpp, full scale (JPEG)
195 			return "PIX_FMT_YUVJ444P";
196 
197 		case PIX_FMT_XVMC_MPEG2_MC:
198 			// XVideo Motion Acceleration via common packet passing
199 			return "PIX_FMT_XVMC_MPEG2_MC";
200 
201 		case PIX_FMT_XVMC_MPEG2_IDCT:
202 			return "PIX_FMT_XVMC_MPEG2_IDCT";
203 		case PIX_FMT_UYVY422:
204 			// packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
205 			return "PIX_FMT_UYVY422";
206 
207 		case PIX_FMT_UYYVYY411:
208 			// packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3
209 			return "PIX_FMT_UYYVYY411";
210 
211 		case PIX_FMT_BGR32:
212 			// packed RGB 8:8:8, 32bpp, (msb)8A 8B 8G 8R(lsb), in CPU
213 			// endianness
214 			return "PIX_FMT_BGR32";
215 
216 		case PIX_FMT_BGR565:
217 			// packed RGB 5:6:5, 16bpp, (msb)5B 6G 5R(lsb), in CPU endianness
218 			return "PIX_FMT_BGR565";
219 
220 		case PIX_FMT_BGR555:
221 			// packed RGB 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), in CPU
222 			// endianness, most significant bit to 1
223 			return "PIX_FMT_BGR555";
224 
225 		case PIX_FMT_BGR8:
226 			// packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
227 			return "PIX_FMT_BGR8";
228 
229 		case PIX_FMT_BGR4:
230 			// packed RGB 1:2:1, 4bpp, (msb)1B 2G 1R(lsb)
231 			return "PIX_FMT_BGR4";
232 
233 		case PIX_FMT_BGR4_BYTE:
234 			// packed RGB 1:2:1,  8bpp, (msb)1B 2G 1R(lsb)
235 			return "PIX_FMT_BGR4_BYTE";
236 
237 		case PIX_FMT_RGB8:
238 			// packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
239 			return "PIX_FMT_RGB8";
240 
241 		case PIX_FMT_RGB4:
242 			// packed RGB 1:2:1, 4bpp, (msb)1R 2G 1B(lsb)
243 			return "PIX_FMT_RGB4";
244 
245 		case PIX_FMT_RGB4_BYTE:
246 			// packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
247 			return "PIX_FMT_RGB4_BYTE";
248 
249 		case PIX_FMT_NV12:
250 			// planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 for UV
251 			return "PIX_FMT_NV12";
252 
253 		case PIX_FMT_NV21:
254 			// as above, but U and V bytes are swapped
255 			return "PIX_FMT_NV21";
256 
257 		case PIX_FMT_RGB32_1:
258 			// packed RGB 8:8:8, 32bpp, (msb)8R 8G 8B 8A(lsb), in CPU
259 			// endianness
260 			return "PIX_FMT_RGB32_1";
261 
262 		case PIX_FMT_BGR32_1:
263 			// packed RGB 8:8:8, 32bpp, (msb)8B 8G 8R 8A(lsb), in CPU
264 			// endianness
265 			return "PIX_FMT_BGR32_1";
266 
267 		case PIX_FMT_GRAY16BE:
268 			// Y, 16bpp, big-endian
269 			return "PIX_FMT_GRAY16BE";
270 
271 		case PIX_FMT_GRAY16LE:
272 			// Y, 16bpp, little-endian
273 			return "PIX_FMT_GRAY16LE";
274 
275 		case PIX_FMT_YUV440P:
276 			// planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
277 			return "PIX_FMT_YUV440P";
278 
279 		case PIX_FMT_YUVJ440P:
280 			// planar YUV 4:4:0 full scale (JPEG)
281 			return "PIX_FMT_YUVJ440P - YUV440P (Jpeg)";
282 
283 		case PIX_FMT_YUVA420P:
284 			// planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A
285 			// samples)
286 			return "PIX_FMT_YUVA420P - YUV420P (Alpha)";
287 
288 		case PIX_FMT_VDPAU_H264:
289 			// H.264 HW decoding with VDPAU, data[0] contains a
290 			// vdpau_render_state struct which contains the bitstream of the
291 			// slices as well as various fields extracted from headers
292 			return "PIX_FMT_VDPAU_H264";
293 
294 		case PIX_FMT_VDPAU_MPEG1:
295 			// MPEG-1 HW decoding with VDPAU, data[0] contains a
296 			// vdpau_render_state struct which contains the bitstream of the
297 			// slices as well as various fields extracted from headers
298 			return "PIX_FMT_VDPAU_MPEG1";
299 
300 		case PIX_FMT_VDPAU_MPEG2:
301 			// MPEG-2 HW decoding with VDPAU, data[0] contains a
302 			// vdpau_render_state struct which contains the bitstream of the
303 			// slices as well as various fields extracted from headers
304 			return "PIX_FMT_VDPAU_MPEG2";
305 
306 		case PIX_FMT_VDPAU_WMV3:
307 			// WMV3 HW decoding with VDPAU, data[0] contains a
308 			// vdpau_render_state struct which contains the bitstream of the
309 			// slices as well as various fields extracted from headers
310 			return "PIX_FMT_VDPAU_WMV3";
311 
312 		case PIX_FMT_VDPAU_VC1:
313 			// VC-1 HW decoding with VDPAU, data[0] contains a
314 			// vdpau_render_state struct which contains the bitstream of the
315 			// slices as well as various fields extracted from headers
316 			return "PIX_FMT_VDPAU_VC1";
317 
318 		case PIX_FMT_RGB48BE:
319 			// packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, big-endian
320 			return "PIX_FMT_RGB48BE";
321 
322 		case PIX_FMT_RGB48LE:
323 			// packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, little-endian
324 			return "PIX_FMT_RGB48LE";
325 
326 		case PIX_FMT_VAAPI_MOCO:
327 			// HW acceleration through VA API at motion compensation
328 			// entry-point, Picture.data[0] contains a vaapi_render_state
329 			// struct which contains macroblocks as well as various fields
330 			// extracted from headers
331 			return "PIX_FMT_VAAPI_MOCO";
332 
333 		case PIX_FMT_VAAPI_IDCT:
334 			// HW acceleration through VA API at IDCT entry-point,
335 			// Picture.data[0] contains a vaapi_render_state struct which
336 			// contains fields extracted from headers
337 			return "PIX_FMT_VAAPI_IDCT";
338 
339 		case PIX_FMT_VAAPI_VLD:
340 			// HW decoding through VA API, Picture.data[0] contains a
341 			// vaapi_render_state struct which contains the bitstream of the
342 			// slices as well as various fields extracted from headers
343 			return "PIX_FMT_VAAPI_VLD";
344 
345 		default:
346 			return "(unknown)";
347 	}
348 }
349 
350 
351 color_space
352 pixfmt_to_colorspace(int pixFormat)
353 {
354 	switch(pixFormat) {
355 		default:
356 			TRACE("No BE API colorspace definition for pixel format "
357 				"\"%s\".\n", pixfmt_to_string(pixFormat));
358 			// Supposed to fall through.
359 		case PIX_FMT_NONE:
360 			return B_NO_COLOR_SPACE;
361 
362 		// NOTE: See pixfmt_to_colorspace() for what these are.
363 		case PIX_FMT_YUV420P:
364 			return B_YUV420;
365 		case PIX_FMT_YUYV422:
366 			return B_YUV422;
367 		case PIX_FMT_RGB24:
368 			return B_RGB24_BIG;
369 		case PIX_FMT_BGR24:
370 			return B_RGB24;
371 		case PIX_FMT_YUV422P:
372 			return B_YUV422;
373 		case PIX_FMT_YUV444P:
374 			return B_YUV444;
375 		case PIX_FMT_RGB32:
376 			return B_RGBA32_BIG;
377 		case PIX_FMT_YUV410P:
378 			return B_YUV9;
379 		case PIX_FMT_YUV411P:
380 			return B_YUV12;
381 		case PIX_FMT_RGB565:
382 			return B_RGB16_BIG;
383 		case PIX_FMT_RGB555:
384 			return B_RGB15_BIG;
385 		case PIX_FMT_GRAY8:
386 			return B_GRAY8;
387 		case PIX_FMT_MONOBLACK:
388 			return B_GRAY1;
389 		case PIX_FMT_PAL8:
390 			return B_CMAP8;
391 		case PIX_FMT_BGR32:
392 			return B_RGB32;
393 		case PIX_FMT_BGR565:
394 			return B_RGB16;
395 		case PIX_FMT_BGR555:
396 			return B_RGB15;
397 	}
398 }
399 
400 
401 PixelFormat
402 colorspace_to_pixfmt(color_space format)
403 {
404 	switch(format) {
405 		default:
406 		case B_NO_COLOR_SPACE:
407 			return PIX_FMT_NONE;
408 
409 		// NOTE: See pixfmt_to_colorspace() for what these are.
410 		case B_YUV420:
411 			return PIX_FMT_YUV420P;
412 		case B_YUV422:
413 			return PIX_FMT_YUV422P;
414 		case B_RGB24_BIG:
415 			return PIX_FMT_RGB24;
416 		case B_RGB24:
417 			return PIX_FMT_BGR24;
418 		case B_YUV444:
419 			return PIX_FMT_YUV444P;
420 		case B_RGBA32_BIG:
421 		case B_RGB32_BIG:
422 			return PIX_FMT_BGR32;
423 		case B_YUV9:
424 			return PIX_FMT_YUV410P;
425 		case B_YUV12:
426 			return PIX_FMT_YUV411P;
427 		// TODO: YCbCr color spaces! These are not the same as YUV!
428 		case B_RGB16_BIG:
429 			return PIX_FMT_RGB565;
430 		case B_RGB15_BIG:
431 			return PIX_FMT_RGB555;
432 		case B_GRAY8:
433 			return PIX_FMT_GRAY8;
434 		case B_GRAY1:
435 			return PIX_FMT_MONOBLACK;
436 		case B_CMAP8:
437 			return PIX_FMT_PAL8;
438 		case B_RGBA32:
439 		case B_RGB32:
440 			return PIX_FMT_RGB32;
441 		case B_RGB16:
442 			return PIX_FMT_BGR565;
443 		case B_RGB15:
444 			return PIX_FMT_BGR555;
445 	}
446 }
447 
448 
449 #define BEGIN_TAG "\033[31m"
450 #define END_TAG "\033[0m"
451 
452 void
453 dump_ffframe(AVFrame* frame, const char* name)
454 {
455 	const char* picttypes[] = {"no pict type", "intra", "predicted",
456 		"bidir pre", "s(gmc)-vop"};
457 	printf(BEGIN_TAG"AVFrame(%s) pts:%-10lld cnum:%-5d dnum:%-5d %s%s, "
458 		" ]\n"END_TAG,
459 		name,
460 		frame->pts,
461 		frame->coded_picture_number,
462 		frame->display_picture_number,
463 //		frame->quality,
464 		frame->key_frame?"keyframe, ":"",
465 		picttypes[frame->pict_type]);
466 //	printf(BEGIN_TAG"\t\tlinesize[] = {%ld, %ld, %ld, %ld}\n"END_TAG,
467 //		frame->linesize[0], frame->linesize[1], frame->linesize[2],
468 //		frame->linesize[3]);
469 }
470 
471