package generator import "fmt" var ebu75Colors = [...]YCbCr10{ {Y: 721, Cb: 512, Cr: 512}, {Y: 674, Cb: 176, Cr: 543}, {Y: 581, Cb: 589, Cr: 176}, {Y: 534, Cb: 253, Cr: 207}, {Y: 251, Cb: 771, Cr: 817}, {Y: 204, Cb: 435, Cr: 848}, {Y: 111, Cb: 848, Cr: 481}, {Y: 64, Cb: 512, Cr: 512}, } var ebu100Colors = [...]YCbCr10{ {Y: 940, Cb: 512, Cr: 512}, {Y: 877, Cb: 64, Cr: 553}, {Y: 754, Cb: 615, Cr: 64}, {Y: 691, Cb: 167, Cr: 105}, {Y: 313, Cb: 857, Cr: 919}, {Y: 250, Cb: 409, Cr: 960}, {Y: 127, Cb: 960, Cr: 471}, {Y: 64, Cb: 512, Cr: 512}, } var grayBarsColors = [...]YCbCr10{ {Y: 64, Cb: 512, Cr: 512}, {Y: 137, Cb: 512, Cr: 512}, {Y: 210, Cb: 512, Cr: 512}, {Y: 283, Cb: 512, Cr: 512}, {Y: 356, Cb: 512, Cr: 512}, {Y: 429, Cb: 512, Cr: 512}, {Y: 502, Cb: 512, Cr: 512}, {Y: 575, Cb: 512, Cr: 512}, {Y: 648, Cb: 512, Cr: 512}, {Y: 721, Cb: 512, Cr: 512}, {Y: 794, Cb: 512, Cr: 512}, {Y: 867, Cb: 512, Cr: 512}, {Y: 940, Cb: 512, Cr: 512}, } var ( ebu75BaseColor = colorBars(ebu75Colors[:]) ebu100BaseColor = colorBars(ebu100Colors[:]) grayBarsBaseColor = colorBars(grayBarsColors[:]) ) func NewCPUPatternGenerator(width, height uint, pattern string) (*CPUGenerator, error) { var baseColor baseColorFunc var dynamic bool switch pattern { case "ebu75": baseColor = ebu75BaseColor case "ebu75-move": baseColor, dynamic = ebu75BaseColor, true case "ebu100": baseColor = ebu100BaseColor case "ebu100-move": baseColor, dynamic = ebu100BaseColor, true case "gray-bars": baseColor = grayBarsBaseColor case "gray-bars-move": baseColor, dynamic = grayBarsBaseColor, true case "gray-ramp": baseColor = grayRampBaseColor case "gray-ramp-move": baseColor, dynamic = grayRampBaseColor, true default: return nil, fmt.Errorf("cpu pattern %q is not implemented", pattern) } var patch FrameRenderer if dynamic { patch = movingSquarePatch(baseColor) } return NewCPUGenerator(width, height, baseRenderer(baseColor), patch) } func grayRampBaseColor(x, _, width, _ int) YCbCr10 { return YCbCr10{ Y: uint32(64 + (x*876)/width), Cb: 512, Cr: 512, } } func colorBars(colors []YCbCr10) baseColorFunc { return func(x, _, width, _ int) YCbCr10 { bar := min(x*len(colors)/width, len(colors)-1) return colors[bar] } } func baseRenderer(baseColor baseColorFunc) FrameRenderer { return func(dst []byte, width, height, _ int) error { return renderBasePattern(dst, width, height, baseColor) } } func movingSquarePatch(baseColor baseColorFunc) FrameRenderer { return func(dst []byte, width, height, frameIndex int) error { return patchMovingSquare(dst, width, height, frameIndex, baseColor) } } func renderBasePattern(dst []byte, width, height int, baseColor baseColorFunc) error { for y := 0; y < height; y++ { for x := 0; x < width; x += 6 { var pixels [6]YCbCr10 for i := range pixels { pixels[i] = baseColor(x+i, y, width, height) } offset := (y*width + x) / 6 * 16 packV210Block(dst[offset:offset+16], pixels) } } return nil }