CMVideoSampling.mm 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #include "CMVideoSampling.h"
  2. #include "CVTextureCache.h"
  3. #include <AVFoundation/AVFoundation.h>
  4. #include "DisplayManager.h" // for GetMainDisplaySurface() to have proper linear/srgb handling
  5. void CMVideoSampling_Initialize(CMVideoSampling* sampling)
  6. {
  7. ::memset(sampling, 0x00, sizeof(CMVideoSampling));
  8. sampling->cvTextureCache = CreateCVTextureCache();
  9. }
  10. void CMVideoSampling_Uninitialize(CMVideoSampling* sampling)
  11. {
  12. if (sampling->cvImageBuffer)
  13. {
  14. CFRelease(sampling->cvImageBuffer);
  15. sampling->cvImageBuffer = 0;
  16. }
  17. if (sampling->cvTextureCacheTexture)
  18. {
  19. CFRelease(sampling->cvTextureCacheTexture);
  20. sampling->cvTextureCacheTexture = 0;
  21. }
  22. if (sampling->cvTextureCache)
  23. {
  24. CFRelease(sampling->cvTextureCache);
  25. sampling->cvTextureCache = 0;
  26. }
  27. }
  28. intptr_t CMVideoSampling_ImageBuffer(CMVideoSampling* sampling, CVImageBufferRef buffer, size_t* w, size_t* h)
  29. {
  30. intptr_t retTex = 0;
  31. if (sampling->cvImageBuffer)
  32. CFRelease(sampling->cvImageBuffer);
  33. sampling->cvImageBuffer = buffer;
  34. CFRetain(sampling->cvImageBuffer);
  35. *w = CVPixelBufferGetWidth((CVImageBufferRef)sampling->cvImageBuffer);
  36. *h = CVPixelBufferGetHeight((CVImageBufferRef)sampling->cvImageBuffer);
  37. if (sampling->cvTextureCacheTexture)
  38. {
  39. CFRelease(sampling->cvTextureCacheTexture);
  40. FlushCVTextureCache(sampling->cvTextureCache);
  41. sampling->cvTextureCacheTexture = nil;
  42. }
  43. OSType pixelFormat = CVPixelBufferGetPixelFormatType(buffer);
  44. if (pixelFormat == kCVPixelFormatType_32BGRA || pixelFormat == kCVPixelFormatType_DepthFloat16)
  45. {
  46. MTLPixelFormat metalFormat32BGRA = GetMainDisplaySurface()->srgb ? MTLPixelFormatBGRA8Unorm_sRGB : MTLPixelFormatBGRA8Unorm;
  47. MTLPixelFormat metalFormat = pixelFormat == kCVPixelFormatType_32BGRA ? metalFormat32BGRA : MTLPixelFormatR16Float;
  48. sampling->cvTextureCacheTexture = CreateTextureFromCVTextureCache2(sampling->cvTextureCache, sampling->cvImageBuffer, *w, *h, metalFormat);
  49. }
  50. else
  51. {
  52. #define FourCC2Str(fourcc) (const char[]){*(((char*)&fourcc)+3), *(((char*)&fourcc)+2), *(((char*)&fourcc)+1), *(((char*)&fourcc)+0),0}
  53. ::printf("CMVideoSampling_SampleBuffer: unexpected pixel format \'%s\'\n", FourCC2Str(pixelFormat));
  54. }
  55. if (sampling->cvTextureCacheTexture)
  56. retTex = GetTextureFromCVTextureCache(sampling->cvTextureCacheTexture);
  57. return retTex;
  58. }
  59. intptr_t CMVideoSampling_SampleBuffer(CMVideoSampling* sampling, void* buffer, size_t* w, size_t* h)
  60. {
  61. return CMVideoSampling_ImageBuffer(sampling, CMSampleBufferGetImageBuffer((CMSampleBufferRef)buffer), w, h);
  62. }
  63. intptr_t CMVideoSampling_LastSampledTexture(CMVideoSampling* sampling)
  64. {
  65. return GetTextureFromCVTextureCache(sampling->cvTextureCacheTexture);
  66. }