h.264動画でmetal処理するときよくyuv video rangeの動画がきていて、 full rang + rgb変換しないと処理できないので、knowhowとして残したいと思ってます。
方法1
自前でmetal変換
fragment float4 yuvVideoRangeToRGBFragmentShader(ColorInOut in [[ stage_in ]],
texture2d<float> baseYTexture [[ texture(0) ]],
texture2d<float> baseCbCrTexture [[ texture(1) ]]) {
constexpr sampler colorSampler;
const float4x4 ycbcrToRGBTransform = float4x4(
float4(+1.0000f, +1.0000f, +1.0000f, +0.0000f),
float4(+0.0000f, -0.3441f, +1.7720f, +0.0000f),
float4(+1.4020f, -0.7141f, +0.0000f, +0.0000f),
float4(-0.7010f, +0.5291f, -0.8860f, +1.0000f)
);
float4 baseYUVColor = float4(baseYTexture.sample(colorSampler, in.texCoords).r,
baseCbCrTexture.sample(colorSampler, in.texCoords).rg,
1.0f);
// yuv video range to full range
baseYUVColor.r = (baseYUVColor.r - (16.0f/255.0f)) * (255.0f/(235.0f-16.0f));
baseYUVColor.g = (baseYUVColor.g - (16.0f/255.0f)) * (255.0f/(240.0f-16.0f));
baseYUVColor.b = (baseYUVColor.b - (16.0f/255.0f)) * (255.0f/(240.0f-16.0f));
// yuv to rgb
float4 baseColor = ycbcrToRGBTransform * baseYUVColor;
return baseColor;
}
方法2
AVAssetReaderTrackOutputのoutputSettingsでfull rangeに指定して、iOS側が変換してくれる
kCVPixelFormatType_420YpCbCr8BiPlanarFullRange は yuv full rangeで、
rgb直欲しい場合はkCVPixelFormatType_32BGRAしてすればいい。
let outputSettings: [String: Any] = [
// full rangeに指定
kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_420YpCbCr8BiPlanarFullRange,
kCVPixelBufferMetalCompatibilityKey as String: true
]
let output = AVAssetReaderTrackOutput(track: asset.tracks(withMediaType: AVMediaType.video)[0], outputSettings: outputSettings)
おわり
方法1のほうがパフォーマンスとしていいが、方法2はOS側処理してくれるので、楽ではあるが、ほかの処理入れたいときにはパフォーマンスちょっと落ちる。
おまけ
hevc with aplha処理
hevc with aplha動画のpixelFormatがkCVPixelFormatType_420YpCbCr8VideoRange_8A_TriPlanarになっていて、
コードのコメント見るとyuv部分はvideo rangeだが、alpha部分はfull rangeなので、
処理するときは要注意。
kCVPixelFormatType_420YpCbCr8VideoRange_8A_TriPlanarソースのコメント:
/* first and second planes as per 420YpCbCr8BiPlanarVideoRange (420v), alpha 8 bits in third plane full-range. No CVPlanarPixelBufferInfo struct. */
参考:
https://developer.apple.com/documentation/corevideo/kcvpixelformattype_420ypcbcr8biplanarvideorange
https://developer.apple.com/documentation/corevideo/kcvpixelformattype_420ypcbcr8biplanarfullrange
https://developer.apple.com/documentation/corevideo/kcvpixelformattype_32bgra