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