closest-pixel-format.h 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #pragma once
  2. static const enum AVPixelFormat i420_formats[] = {
  3. AV_PIX_FMT_YUV420P, AV_PIX_FMT_NV12, AV_PIX_FMT_NV21,
  4. AV_PIX_FMT_YUYV422, AV_PIX_FMT_UYVY422, AV_PIX_FMT_YUV422P,
  5. AV_PIX_FMT_YUV444P, AV_PIX_FMT_NONE};
  6. static const enum AVPixelFormat nv12_formats[] = {
  7. AV_PIX_FMT_NV12, AV_PIX_FMT_NV21, AV_PIX_FMT_YUV420P,
  8. AV_PIX_FMT_YUYV422, AV_PIX_FMT_UYVY422, AV_PIX_FMT_YUV444P,
  9. AV_PIX_FMT_NONE};
  10. static const enum AVPixelFormat i444_formats[] = {
  11. AV_PIX_FMT_YUV444P, AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA,
  12. AV_PIX_FMT_YUYV422, AV_PIX_FMT_UYVY422, AV_PIX_FMT_NV12,
  13. AV_PIX_FMT_NV21, AV_PIX_FMT_NONE};
  14. static const enum AVPixelFormat yuy2_formats[] = {
  15. AV_PIX_FMT_YUYV422, AV_PIX_FMT_UYVY422, AV_PIX_FMT_NV12,
  16. AV_PIX_FMT_NV21, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV444P,
  17. AV_PIX_FMT_NONE};
  18. static const enum AVPixelFormat uyvy_formats[] = {
  19. AV_PIX_FMT_UYVY422, AV_PIX_FMT_YUYV422, AV_PIX_FMT_NV12,
  20. AV_PIX_FMT_NV21, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV444P,
  21. AV_PIX_FMT_NONE};
  22. static const enum AVPixelFormat rgba_formats[] = {
  23. AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, AV_PIX_FMT_YUV444P,
  24. AV_PIX_FMT_YUYV422, AV_PIX_FMT_UYVY422, AV_PIX_FMT_NV12,
  25. AV_PIX_FMT_NV21, AV_PIX_FMT_NONE};
  26. static const enum AVPixelFormat bgra_formats[] = {
  27. AV_PIX_FMT_BGRA, AV_PIX_FMT_RGBA, AV_PIX_FMT_YUV444P,
  28. AV_PIX_FMT_YUYV422, AV_PIX_FMT_UYVY422, AV_PIX_FMT_NV12,
  29. AV_PIX_FMT_NV21, AV_PIX_FMT_NONE};
  30. static enum AVPixelFormat get_best_format(const enum AVPixelFormat *best,
  31. const enum AVPixelFormat *formats)
  32. {
  33. while (*best != AV_PIX_FMT_NONE) {
  34. enum AVPixelFormat best_format = *best;
  35. const enum AVPixelFormat *cur_formats = formats;
  36. while (*cur_formats != AV_PIX_FMT_NONE) {
  37. enum AVPixelFormat avail_format = *cur_formats;
  38. if (best_format == avail_format)
  39. return best_format;
  40. cur_formats++;
  41. }
  42. best++;
  43. }
  44. return AV_PIX_FMT_NONE;
  45. }
  46. static inline enum AVPixelFormat
  47. get_closest_format(enum AVPixelFormat format, const enum AVPixelFormat *formats)
  48. {
  49. enum AVPixelFormat best_format = AV_PIX_FMT_NONE;
  50. if (!formats || formats[0] == AV_PIX_FMT_NONE)
  51. return format;
  52. switch ((int)format) {
  53. case AV_PIX_FMT_YUV444P:
  54. best_format = get_best_format(i444_formats, formats);
  55. break;
  56. case AV_PIX_FMT_YUV420P:
  57. best_format = get_best_format(i420_formats, formats);
  58. break;
  59. case AV_PIX_FMT_NV12:
  60. best_format = get_best_format(nv12_formats, formats);
  61. break;
  62. case AV_PIX_FMT_YUYV422:
  63. best_format = get_best_format(yuy2_formats, formats);
  64. break;
  65. case AV_PIX_FMT_UYVY422:
  66. best_format = get_best_format(uyvy_formats, formats);
  67. break;
  68. case AV_PIX_FMT_RGBA:
  69. best_format = get_best_format(rgba_formats, formats);
  70. break;
  71. case AV_PIX_FMT_BGRA:
  72. best_format = get_best_format(bgra_formats, formats);
  73. break;
  74. }
  75. return (best_format == AV_PIX_FMT_NONE) ? formats[0] : best_format;
  76. }