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, AVPixelFormat pixelFormat, int width, 30 int height) 31 { 32 CPUCapabilities cpu; 33 34 switch (colorSpace) { 35 case B_RGB32: 36 // Planar Formats 37 if (pixelFormat == AV_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 == AV_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 == AV_PIX_FMT_YUV420P 48 || pixelFormat == AV_PIX_FMT_YUVJ420P) { 49 #if 0 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 == AV_PIX_FMT_YUV422P 67 || pixelFormat == AV_PIX_FMT_YUVJ422P) { 68 #if 0 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 if (pixelFormat == AV_PIX_FMT_GBRP) { 85 return gfx_conv_GBRP_RGB32_c; 86 } 87 88 // Packed Formats 89 if (pixelFormat == AV_PIX_FMT_YUYV422) { 90 #if 0 91 if (cpu.HasSSSE3() && width % 8 == 0) { 92 return gfx_conv_yuv422_rgba32_ssse3; 93 } else if (cpu.HasSSE2() && width % 8 == 0) { 94 return gfx_conv_yuv422_rgba32_sse2; 95 } else if (cpu.HasSSE1() && width % 4 == 0 96 && height % 2 == 0) { 97 return gfx_conv_yuv422_rgba32_sse; 98 } 99 #endif 100 return gfx_conv_YCbCr422_RGB32_c; 101 } 102 103 if (pixelFormat == AV_PIX_FMT_YUV420P10LE) 104 return gfx_conv_yuv420p10le_rgb32_c; 105 106 TRACE("resolve_colorspace: %s => B_RGB32: NULL\n", 107 pixfmt_to_string(pixelFormat)); 108 return NULL; 109 110 case B_RGB24_BIG: 111 TRACE("resolve_colorspace: %s => B_RGB24_BIG: NULL\n", 112 pixfmt_to_string(pixelFormat)); 113 return NULL; 114 115 case B_RGB24: 116 TRACE("resolve_colorspace: %s => B_RGB24: NULL\n", 117 pixfmt_to_string(pixelFormat)); 118 return NULL; 119 120 case B_YCbCr422: 121 if (pixelFormat == AV_PIX_FMT_YUV410P) { 122 TRACE("resolve_colorspace: gfx_conv_yuv410p_ycbcr422_c\n"); 123 return gfx_conv_yuv410p_ycbcr422_c; 124 } 125 126 if (pixelFormat == AV_PIX_FMT_YUV411P) { 127 TRACE("resolve_colorspace: gfx_conv_yuv411p_ycbcr422_c\n"); 128 return gfx_conv_yuv411p_ycbcr422_c; 129 } 130 131 if (pixelFormat == AV_PIX_FMT_YUV420P 132 || pixelFormat == AV_PIX_FMT_YUVJ420P) { 133 TRACE("resolve_colorspace: gfx_conv_yuv420p_ycbcr422_c\n"); 134 return gfx_conv_yuv420p_ycbcr422_c; 135 } 136 137 if (pixelFormat == AV_PIX_FMT_YUYV422) { 138 TRACE("resolve_colorspace: PIX_FMT_YUV422 => B_YCbCr422: " 139 "gfx_conv_null\n"); 140 return gfx_conv_null; 141 } 142 143 TRACE("resolve_colorspace: %s => B_YCbCr422: NULL\n", 144 pixfmt_to_string(pixelFormat)); 145 return NULL; 146 147 default: 148 TRACE("resolve_colorspace: default: NULL!!!\n"); 149 return NULL; 150 } 151 } 152 153 154 const char* 155 pixfmt_to_string(int pixFormat) 156 { 157 const char* name = av_get_pix_fmt_name((enum AVPixelFormat)pixFormat); 158 if (name == NULL) 159 return "(unknown)"; 160 return name; 161 } 162 163 164 color_space 165 pixfmt_to_colorspace(int pixFormat) 166 { 167 switch (pixFormat) { 168 default: 169 TRACE("No BE API colorspace definition for pixel format " 170 "\"%s\".\n", pixfmt_to_string(pixFormat)); 171 // Supposed to fall through. 172 case AV_PIX_FMT_NONE: 173 return B_NO_COLOR_SPACE; 174 175 // NOTE: See pixfmt_to_colorspace() for what these are. 176 case AV_PIX_FMT_YUV420P: 177 return B_YUV420; 178 case AV_PIX_FMT_RGB24: 179 return B_RGB24_BIG; 180 case AV_PIX_FMT_BGR24: 181 return B_RGB24; 182 case AV_PIX_FMT_YUV422P: 183 return B_YUV422; 184 case AV_PIX_FMT_YUV444P: 185 return B_YUV444; 186 case AV_PIX_FMT_RGB32: 187 return B_RGBA32_BIG; 188 case AV_PIX_FMT_YUV410P: 189 return B_YUV9; 190 case AV_PIX_FMT_YUV411P: 191 return B_YUV12; 192 case AV_PIX_FMT_RGB565: 193 return B_RGB16_BIG; 194 case AV_PIX_FMT_RGB555: 195 return B_RGB15_BIG; 196 case AV_PIX_FMT_GRAY8: 197 return B_GRAY8; 198 case AV_PIX_FMT_MONOBLACK: 199 return B_GRAY1; 200 case AV_PIX_FMT_PAL8: 201 return B_CMAP8; 202 case AV_PIX_FMT_BGR32: 203 return B_RGB32; 204 case AV_PIX_FMT_BGR565: 205 return B_RGB16; 206 case AV_PIX_FMT_BGR555: 207 return B_RGB15; 208 // TODO: more YCbCr color spaces! These are not the same as YUV! 209 case AV_PIX_FMT_YUYV422: 210 return B_YCbCr422; 211 212 } 213 } 214 215 216 AVPixelFormat 217 colorspace_to_pixfmt(color_space format) 218 { 219 switch(format) { 220 default: 221 case B_NO_COLOR_SPACE: 222 return AV_PIX_FMT_NONE; 223 224 // NOTE: See pixfmt_to_colorspace() for what these are. 225 case B_YUV420: 226 return AV_PIX_FMT_YUV420P; 227 case B_YUV422: 228 return AV_PIX_FMT_YUV422P; 229 case B_RGB24_BIG: 230 return AV_PIX_FMT_RGB24; 231 case B_RGB24: 232 return AV_PIX_FMT_BGR24; 233 case B_YUV444: 234 return AV_PIX_FMT_YUV444P; 235 case B_RGBA32_BIG: 236 case B_RGB32_BIG: 237 return AV_PIX_FMT_BGR32; 238 case B_YUV9: 239 return AV_PIX_FMT_YUV410P; 240 case B_YUV12: 241 return AV_PIX_FMT_YUV411P; 242 case B_RGB16_BIG: 243 return AV_PIX_FMT_RGB565; 244 case B_RGB15_BIG: 245 return AV_PIX_FMT_RGB555; 246 case B_GRAY8: 247 return AV_PIX_FMT_GRAY8; 248 case B_GRAY1: 249 return AV_PIX_FMT_MONOBLACK; 250 case B_CMAP8: 251 return AV_PIX_FMT_PAL8; 252 case B_RGBA32: 253 case B_RGB32: 254 return AV_PIX_FMT_RGB32; 255 case B_RGB16: 256 return AV_PIX_FMT_BGR565; 257 case B_RGB15: 258 return AV_PIX_FMT_BGR555; 259 // TODO: more YCbCr color spaces! These are not the same as YUV! 260 case B_YCbCr422: 261 return AV_PIX_FMT_YUYV422; 262 } 263 } 264 265 266 #define BEGIN_TAG "\033[31m" 267 #define END_TAG "\033[0m" 268 269 void 270 dump_ffframe_audio(AVFrame* frame, const char* name) 271 { 272 printf(BEGIN_TAG "AVFrame(%s) [ pkt_dts:%-10" PRId64 " #samples:%-5d %s" 273 " ]\n" END_TAG, 274 name, 275 frame->pkt_dts, 276 frame->nb_samples, 277 av_get_sample_fmt_name(static_cast<AVSampleFormat>(frame->format))); 278 } 279 280 281 void 282 dump_ffframe_video(AVFrame* frame, const char* name) 283 { 284 const char* picttypes[] = {"no pict type", "intra", "predicted", 285 "bidir pre", "s(gmc)-vop", "switching intra", "switching predicted", "BI"}; 286 #if LIBAVCODEC_VERSION_MAJOR >= 60 287 printf(BEGIN_TAG "AVFrame(%s) [ pkt_dts:%-10" PRId64 " %s%s%s%s%s%s ]\n" END_TAG, name, 288 frame->pkt_dts, 289 (frame->flags & AV_FRAME_FLAG_CORRUPT) ? "corrupt, " : "", 290 (frame->flags & AV_FRAME_FLAG_KEY) ? "keyframe, " : "", 291 (frame->flags & AV_FRAME_FLAG_DISCARD) ? "discard, " : "", 292 (frame->flags & AV_FRAME_FLAG_INTERLACED) ? "interlaced, " : "", 293 (frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? "top field first, " : "", 294 picttypes[frame->pict_type]); 295 #else 296 printf(BEGIN_TAG "AVFrame(%s) [ pkt_dts:%-10" PRId64 " %s%s ]\n" END_TAG, name, frame->pkt_dts, 297 frame->key_frame ? "keyframe, " : "", picttypes[frame->pict_type]); 298 #endif 299 } 300