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