flutter-hdr

flutter

flutter 播放 HDR 视频,色彩跟亮度都有问题 ,github 也有反馈这个issue Video Player HDR Problem 跟原生的对比可以很明显看到差距,官方看起来好像也不重视这个问题 😕

关于 HDR 格式,可以看下前面的文章 HDR笔记

这里记录下Flutter video player plugin 中处理视频色彩的方法,亮度提升需要通过硬件激活,Flutter中好像没法处理。

颜色的处理核心就是做了一个HDR->SDRtonemap,恰好CIImage中提供了这样的Filter,处理就方便多了,
看过HDR笔记 这篇文章的话,应该也可以自己通过 EOTF + 色域映射 来处理。暂时不知道 CIImage中是怎么处理的,猜测是差不多的。

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
- (CVPixelBufferRef)pixelBufferFormCIImage:(CIImage *)image {
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
@{}, kCVPixelBufferIOSurfacePropertiesKey,
@YES, kCVPixelBufferCGImageCompatibilityKey,
@YES, kCVPixelBufferCGBitmapContextCompatibilityKey, nil];

CVPixelBufferRef pixelBufferCopy = NULL;
CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault,
image.extent.size.width,
image.extent.size.height,
kCVPixelFormatType_32BGRA,
(__bridge CFDictionaryRef) options,
&pixelBufferCopy);

if (status == kCVReturnSuccess) {
CIRenderDestination *destination = [[CIRenderDestination alloc] initWithPixelBuffer:pixelBufferCopy];
[self.mContext startTaskToRender:image toDestination:destination error:nil];
}
return pixelBufferCopy;
}

- (CVPixelBufferRef)copyPixelBuffer {
CMTime outputItemTime = [_videoOutput itemTimeForHostTime:CACurrentMediaTime()];
if ([_videoOutput hasNewPixelBufferForItemTime:outputItemTime]) {

CVPixelBufferRef p = [_videoOutput copyPixelBufferForItemTime:outputItemTime itemTimeForDisplay:NULL];
CFTypeRef colorPrimaries = CVBufferGetAttachment(p, kCVImageBufferTransferFunctionKey, NULL);
if (colorPrimaries && CFEqual(colorPrimaries, kCVImageBufferTransferFunction_ITU_R_2100_HLG)) {
if (@available(iOS 14.1, *)) {
CIImage *image = [CIImage imageWithCVPixelBuffer:p options:@{kCIImageToneMapHDRtoSDR : @(YES)}];
CVPixelBufferRef newP = [self pixelBufferFormCIImage:image];
CVPixelBufferRelease(p);
return newP;
}
}
return p;
} else {
return NULL;
}
}