1 #include "gfx_util.h" 2 3 #include <strings.h> 4 #include <stdio.h> 5 6 extern "C" { 7 #include <libavutil/pixdesc.h> 8 } 9 10 #include "CpuCapabilities.h" 11 #include "gfx_conv_c.h" 12 #include "gfx_conv_mmx.h" 13 14 15 // ref docs 16 // http://www.joemaller.com/fcp/fxscript_yuv_color.shtml 17 18 19 #if DEBUG 20 #define TRACE(a...) printf(a) 21 #else 22 #define TRACE(a...) 23 #endif 24 25 #if LIBAVCODEC_VERSION_INT < ((54 << 16) | (50 << 8)) 26 #define AVPixelFormat PixelFormat 27 #define AV_PIX_FMT_NONE PIX_FMT_NONE 28 #define AV_PIX_FMT_YUV410P PIX_FMT_YUV410P 29 #define AV_PIX_FMT_YUV411P PIX_FMT_YUV411P 30 #define AV_PIX_FMT_YUV420P PIX_FMT_YUV420P 31 #define AV_PIX_FMT_YUVJ420P PIX_FMT_YUVJ420P 32 #define AV_PIX_FMT_YUV422P PIX_FMT_YUV422P 33 #define AV_PIX_FMT_YUVJ422P PIX_FMT_YUVJ422P 34 #define AV_PIX_FMT_YUYV422 PIX_FMT_YUYV422 35 #define AV_PIX_FMT_YUV420P10LE PIX_FMT_YUV420P10LE 36 #define AV_PIX_FMT_YUV444P PIX_FMT_YUV444P 37 #define AV_PIX_FMT_RGB24 PIX_FMT_RGB24 38 #define AV_PIX_FMT_BGR24 PIX_FMT_BGR24 39 #define AV_PIX_FMT_RGB565 PIX_FMT_RGB565 40 #define AV_PIX_FMT_RGB555 PIX_FMT_RGB555 41 #define AV_PIX_FMT_GRAY8 PIX_FMT_GRAY8 42 #define AV_PIX_FMT_MONOBLACK PIX_FMT_MONOBLACK 43 #define AV_PIX_FMT_PAL8 PIX_FMT_PAL8 44 #define AV_PIX_FMT_BGR32 PIX_FMT_BGR32 45 #define AV_PIX_FMT_BGR565 PIX_FMT_BGR565 46 #define AV_PIX_FMT_BGR555 PIX_FMT_BGR555 47 #define AV_PIX_FMT_RGB32 PIX_FMT_RGB32 48 #define AV_PIX_FMT_GBRP PIX_FMT_GBRP 49 #endif 50 51 52 //! This function will try to find the best colorspaces for both the ff-codec 53 // and the Media Kit sides. 54 gfx_convert_func 55 resolve_colorspace(color_space colorSpace, AVPixelFormat pixelFormat, int width, 56 int height) 57 { 58 CPUCapabilities cpu; 59 60 switch (colorSpace) { 61 case B_RGB32: 62 // Planar Formats 63 if (pixelFormat == AV_PIX_FMT_YUV410P) { 64 TRACE("resolve_colorspace: gfx_conv_yuv410p_rgb32_c\n"); 65 return gfx_conv_yuv410p_rgb32_c; 66 } 67 68 if (pixelFormat == AV_PIX_FMT_YUV411P) { 69 TRACE("resolve_colorspace: gfx_conv_yuv411p_rgb32_c\n"); 70 return gfx_conv_yuv411p_rgb32_c; 71 } 72 73 if (pixelFormat == AV_PIX_FMT_YUV420P 74 || pixelFormat == AV_PIX_FMT_YUVJ420P) { 75 #ifndef __x86_64__ 76 if (cpu.HasSSSE3() && width % 8 == 0 && height % 2 == 0) { 77 TRACE("resolve_colorspace: gfx_conv_yuv420p_rgba32_ssse3\n"); 78 return gfx_conv_yuv420p_rgba32_ssse3; 79 } else if (cpu.HasSSE2() && width % 8 == 0 && height % 2 == 0) { 80 TRACE("resolve_colorspace: gfx_conv_yuv420p_rgba32_sse2\n"); 81 return gfx_conv_yuv420p_rgba32_sse2; 82 } else if (cpu.HasSSE1() && width % 4 == 0 83 && height % 2 == 0) { 84 TRACE("resolve_colorspace: gfx_conv_yuv420p_rgba32_sse\n"); 85 return gfx_conv_yuv420p_rgba32_sse; 86 } 87 #endif 88 TRACE("resolve_colorspace: gfx_conv_YCbCr420p_RGB32_c\n"); 89 return gfx_conv_YCbCr420p_RGB32_c; 90 } 91 92 if (pixelFormat == AV_PIX_FMT_YUV422P 93 || pixelFormat == AV_PIX_FMT_YUVJ422P) { 94 #ifndef __x86_64__ 95 if (cpu.HasSSSE3() && width % 8 == 0) { 96 TRACE("resolve_colorspace: gfx_conv_yuv422p_RGB32_ssse3\n"); 97 return gfx_conv_yuv422p_rgba32_ssse3; 98 } else if (cpu.HasSSE2() && width % 8 == 0) { 99 TRACE("resolve_colorspace: gfx_conv_yuv422p_RGB32_sse2\n"); 100 return gfx_conv_yuv422p_rgba32_sse2; 101 } else if (cpu.HasSSE1() && width % 4 == 0) { 102 TRACE("resolve_colorspace: gfx_conv_yuv422p_RGB32_sse\n"); 103 return gfx_conv_yuv422p_rgba32_sse; 104 } 105 #endif 106 TRACE("resolve_colorspace: gfx_conv_YCbCr422p_RGB32_c\n"); 107 return gfx_conv_YCbCr422_RGB32_c; 108 } 109 110 if (pixelFormat == AV_PIX_FMT_GBRP) { 111 return gfx_conv_GBRP_RGB32_c; 112 } 113 114 // Packed Formats 115 if (pixelFormat == AV_PIX_FMT_YUYV422) { 116 #ifndef __x86_64__ 117 if (cpu.HasSSSE3() && width % 8 == 0) { 118 return gfx_conv_yuv422_rgba32_ssse3; 119 } else if (cpu.HasSSE2() && width % 8 == 0) { 120 return gfx_conv_yuv422_rgba32_sse2; 121 } else if (cpu.HasSSE1() && width % 4 == 0 122 && height % 2 == 0) { 123 return gfx_conv_yuv422_rgba32_sse; 124 } 125 #endif 126 return gfx_conv_YCbCr422_RGB32_c; 127 } 128 129 if (pixelFormat == AV_PIX_FMT_YUV420P10LE) 130 return gfx_conv_yuv420p10le_rgb32_c; 131 132 TRACE("resolve_colorspace: %s => B_RGB32: NULL\n", 133 pixfmt_to_string(pixelFormat)); 134 return NULL; 135 136 case B_RGB24_BIG: 137 TRACE("resolve_colorspace: %s => B_RGB24_BIG: NULL\n", 138 pixfmt_to_string(pixelFormat)); 139 return NULL; 140 141 case B_RGB24: 142 TRACE("resolve_colorspace: %s => B_RGB24: NULL\n", 143 pixfmt_to_string(pixelFormat)); 144 return NULL; 145 146 case B_YCbCr422: 147 if (pixelFormat == AV_PIX_FMT_YUV410P) { 148 TRACE("resolve_colorspace: gfx_conv_yuv410p_ycbcr422_c\n"); 149 return gfx_conv_yuv410p_ycbcr422_c; 150 } 151 152 if (pixelFormat == AV_PIX_FMT_YUV411P) { 153 TRACE("resolve_colorspace: gfx_conv_yuv411p_ycbcr422_c\n"); 154 return gfx_conv_yuv411p_ycbcr422_c; 155 } 156 157 if (pixelFormat == AV_PIX_FMT_YUV420P 158 || pixelFormat == AV_PIX_FMT_YUVJ420P) { 159 TRACE("resolve_colorspace: gfx_conv_yuv420p_ycbcr422_c\n"); 160 return gfx_conv_yuv420p_ycbcr422_c; 161 } 162 163 if (pixelFormat == AV_PIX_FMT_YUYV422) { 164 TRACE("resolve_colorspace: PIX_FMT_YUV422 => B_YCbCr422: " 165 "gfx_conv_null\n"); 166 return gfx_conv_null; 167 } 168 169 TRACE("resolve_colorspace: %s => B_YCbCr422: NULL\n", 170 pixfmt_to_string(pixelFormat)); 171 return NULL; 172 173 default: 174 TRACE("resolve_colorspace: default: NULL!!!\n"); 175 return NULL; 176 } 177 } 178 179 180 const char* 181 pixfmt_to_string(int pixFormat) 182 { 183 const char* name = av_get_pix_fmt_name((enum AVPixelFormat)pixFormat); 184 if (name == NULL) 185 return "(unknown)"; 186 return name; 187 } 188 189 190 color_space 191 pixfmt_to_colorspace(int pixFormat) 192 { 193 switch (pixFormat) { 194 default: 195 TRACE("No BE API colorspace definition for pixel format " 196 "\"%s\".\n", pixfmt_to_string(pixFormat)); 197 // Supposed to fall through. 198 case AV_PIX_FMT_NONE: 199 return B_NO_COLOR_SPACE; 200 201 // NOTE: See pixfmt_to_colorspace() for what these are. 202 case AV_PIX_FMT_YUV420P: 203 return B_YUV420; 204 case AV_PIX_FMT_YUYV422: 205 return B_YUV422; 206 case AV_PIX_FMT_RGB24: 207 return B_RGB24_BIG; 208 case AV_PIX_FMT_BGR24: 209 return B_RGB24; 210 case AV_PIX_FMT_YUV422P: 211 return B_YUV422; 212 case AV_PIX_FMT_YUV444P: 213 return B_YUV444; 214 case AV_PIX_FMT_RGB32: 215 return B_RGBA32_BIG; 216 case AV_PIX_FMT_YUV410P: 217 return B_YUV9; 218 case AV_PIX_FMT_YUV411P: 219 return B_YUV12; 220 case AV_PIX_FMT_RGB565: 221 return B_RGB16_BIG; 222 case AV_PIX_FMT_RGB555: 223 return B_RGB15_BIG; 224 case AV_PIX_FMT_GRAY8: 225 return B_GRAY8; 226 case AV_PIX_FMT_MONOBLACK: 227 return B_GRAY1; 228 case AV_PIX_FMT_PAL8: 229 return B_CMAP8; 230 case AV_PIX_FMT_BGR32: 231 return B_RGB32; 232 case AV_PIX_FMT_BGR565: 233 return B_RGB16; 234 case AV_PIX_FMT_BGR555: 235 return B_RGB15; 236 } 237 } 238 239 240 AVPixelFormat 241 colorspace_to_pixfmt(color_space format) 242 { 243 switch(format) { 244 default: 245 case B_NO_COLOR_SPACE: 246 return AV_PIX_FMT_NONE; 247 248 // NOTE: See pixfmt_to_colorspace() for what these are. 249 case B_YUV420: 250 return AV_PIX_FMT_YUV420P; 251 case B_YUV422: 252 return AV_PIX_FMT_YUV422P; 253 case B_RGB24_BIG: 254 return AV_PIX_FMT_RGB24; 255 case B_RGB24: 256 return AV_PIX_FMT_BGR24; 257 case B_YUV444: 258 return AV_PIX_FMT_YUV444P; 259 case B_RGBA32_BIG: 260 case B_RGB32_BIG: 261 return AV_PIX_FMT_BGR32; 262 case B_YUV9: 263 return AV_PIX_FMT_YUV410P; 264 case B_YUV12: 265 return AV_PIX_FMT_YUV411P; 266 // TODO: YCbCr color spaces! These are not the same as YUV! 267 case B_RGB16_BIG: 268 return AV_PIX_FMT_RGB565; 269 case B_RGB15_BIG: 270 return AV_PIX_FMT_RGB555; 271 case B_GRAY8: 272 return AV_PIX_FMT_GRAY8; 273 case B_GRAY1: 274 return AV_PIX_FMT_MONOBLACK; 275 case B_CMAP8: 276 return AV_PIX_FMT_PAL8; 277 case B_RGBA32: 278 case B_RGB32: 279 return AV_PIX_FMT_RGB32; 280 case B_RGB16: 281 return AV_PIX_FMT_BGR565; 282 case B_RGB15: 283 return AV_PIX_FMT_BGR555; 284 } 285 } 286 287 288 #define BEGIN_TAG "\033[31m" 289 #define END_TAG "\033[0m" 290 291 void 292 dump_ffframe_audio(AVFrame* frame, const char* name) 293 { 294 printf(BEGIN_TAG "AVFrame(%s) [ pkt_dts:%-10lld #samples:%-5d %s" 295 " ]\n" END_TAG, 296 name, 297 frame->pkt_dts, 298 frame->nb_samples, 299 av_get_sample_fmt_name(static_cast<AVSampleFormat>(frame->format))); 300 } 301 302 303 void 304 dump_ffframe_video(AVFrame* frame, const char* name) 305 { 306 const char* picttypes[] = {"no pict type", "intra", "predicted", 307 "bidir pre", "s(gmc)-vop"}; 308 printf(BEGIN_TAG "AVFrame(%s) [ pkt_dts:%-10lld cnum:%-5d dnum:%-5d %s%s" 309 " ]\n" END_TAG, 310 name, 311 frame->pkt_dts, 312 frame->coded_picture_number, 313 frame->display_picture_number, 314 frame->key_frame?"keyframe, ":"", 315 picttypes[frame->pict_type]); 316 } 317