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