CMVideoSampling.mm 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #include "CMVideoSampling.h"
  2. #include "CVTextureCache.h"
  3. #include "GlesHelper.h"
  4. #include <OpenGLES/ES3/glext.h>
  5. #include <AVFoundation/AVFoundation.h>
  6. void CMVideoSampling_Initialize(CMVideoSampling* sampling)
  7. {
  8. ::memset(sampling, 0x00, sizeof(CMVideoSampling));
  9. sampling->cvTextureCache = CreateCVTextureCache();
  10. }
  11. void CMVideoSampling_Uninitialize(CMVideoSampling* sampling)
  12. {
  13. if (sampling->cvImageBuffer)
  14. {
  15. CFRelease(sampling->cvImageBuffer);
  16. sampling->cvImageBuffer = 0;
  17. }
  18. if (sampling->cvTextureCacheTexture)
  19. {
  20. CFRelease(sampling->cvTextureCacheTexture);
  21. sampling->cvTextureCacheTexture = 0;
  22. }
  23. if (sampling->cvTextureCache)
  24. {
  25. CFRelease(sampling->cvTextureCache);
  26. sampling->cvTextureCache = 0;
  27. }
  28. }
  29. intptr_t CMVideoSampling_ImageBuffer(CMVideoSampling* sampling, CVImageBufferRef buffer, size_t* w, size_t* h)
  30. {
  31. intptr_t retTex = 0;
  32. if (sampling->cvImageBuffer)
  33. CFRelease(sampling->cvImageBuffer);
  34. sampling->cvImageBuffer = buffer;
  35. CFRetain(sampling->cvImageBuffer);
  36. *w = CVPixelBufferGetWidth((CVImageBufferRef)sampling->cvImageBuffer);
  37. *h = CVPixelBufferGetHeight((CVImageBufferRef)sampling->cvImageBuffer);
  38. if (sampling->cvTextureCacheTexture)
  39. {
  40. CFRelease(sampling->cvTextureCacheTexture);
  41. FlushCVTextureCache(sampling->cvTextureCache);
  42. sampling->cvTextureCacheTexture = nil;
  43. }
  44. OSType pixelFormat = CVPixelBufferGetPixelFormatType(buffer);
  45. switch (pixelFormat)
  46. {
  47. case kCVPixelFormatType_32BGRA:
  48. sampling->cvTextureCacheTexture = CreateBGRA32TextureFromCVTextureCache(sampling->cvTextureCache, sampling->cvImageBuffer, *w, *h);
  49. break;
  50. #if UNITY_HAS_IOSSDK_11_0
  51. case kCVPixelFormatType_DepthFloat16:
  52. sampling->cvTextureCacheTexture = CreateHalfFloatTextureFromCVTextureCache(sampling->cvTextureCache, sampling->cvImageBuffer, *w, *h);
  53. break;
  54. #endif
  55. default:
  56. #define FourCC2Str(fourcc) (const char[]){*(((char*)&fourcc)+3), *(((char*)&fourcc)+2), *(((char*)&fourcc)+1), *(((char*)&fourcc)+0),0}
  57. ::printf("CMVideoSampling_SampleBuffer: unexpected pixel format \'%s\'\n", FourCC2Str(pixelFormat));
  58. break;
  59. }
  60. if (sampling->cvTextureCacheTexture)
  61. retTex = GetTextureFromCVTextureCache(sampling->cvTextureCacheTexture);
  62. if (UnitySelectedRenderingAPI() == apiOpenGLES2 || UnitySelectedRenderingAPI() == apiOpenGLES3)
  63. {
  64. GLint oldTexBinding = 0;
  65. glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexBinding);
  66. glBindTexture(GL_TEXTURE_2D, (GLuint)retTex);
  67. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  68. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  69. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  70. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  71. glBindTexture(GL_TEXTURE_2D, oldTexBinding);
  72. }
  73. return retTex;
  74. }
  75. intptr_t CMVideoSampling_SampleBuffer(CMVideoSampling* sampling, void* buffer, size_t* w, size_t* h)
  76. {
  77. return CMVideoSampling_ImageBuffer(sampling, CMSampleBufferGetImageBuffer((CMSampleBufferRef)buffer), w, h);
  78. }
  79. intptr_t CMVideoSampling_LastSampledTexture(CMVideoSampling* sampling)
  80. {
  81. return GetTextureFromCVTextureCache(sampling->cvTextureCacheTexture);
  82. }