~emersion/go-kdf

143225ea6860aa699a4c191388a7128cd6da9a0c — Simon Ser 1 year, 4 months ago 55c130e
drm: add packed YUV formats
1 files changed, 83 insertions(+), 10 deletions(-)

M drm/drm.go
M drm/drm.go => drm/drm.go +83 -10
@@ 92,6 92,15 @@ func parseRGBAPackedFormat(s string) (channels []kdf.Channel, bitsPerChannel []i
}

func genRGBAPacked(channels []kdf.Channel, bitsPerChannel []int) *kdf.Block {
	return kdf.NewBlockBasic(&kdf.BlockBasic{
		ColorModel:          kdf.ColorModelRGBSDA,
		TexelBlockDimension: [4]int{1, 1, 1, 1},
		BytesPlane:          []uint8{getBytesPerPixel(bitsPerChannel)},
		SampleInfo:          genPackedSamples(channels, bitsPerChannel),
	})
}

func genPackedSamples(channels []kdf.Channel, bitsPerChannel []int) []kdf.SampleInfo {
	var bitOffset int
	var sampleInfo []kdf.SampleInfo
	for i, ch := range channels {


@@ 106,18 115,19 @@ func genRGBAPacked(channels []kdf.Channel, bitsPerChannel []int) *kdf.Block {
		}
		bitOffset += bitsPerChannel[i]
	}
	return sampleInfo
}

	bytesPerPixel := bitOffset / 8
	if bitOffset%8 != 0 {
		bytesPerPixel++
func getBytesPerPixel(bitsPerChannel []int) uint8 {
	totalBits := 0
	for _, n := range bitsPerChannel {
		totalBits += n
	}

	return kdf.NewBlockBasic(&kdf.BlockBasic{
		ColorModel:          kdf.ColorModelRGBSDA,
		TexelBlockDimension: [4]int{1, 1, 1, 1},
		BytesPlane:          []uint8{uint8(bytesPerPixel)},
		SampleInfo:          sampleInfo,
	})
	totalBytes := totalBits / 8
	if totalBits%8 != 0 {
		totalBytes++
	}
	return uint8(totalBytes)
}

var twoPlaneRGBAFormats = []Format{


@@ 151,6 161,64 @@ func genRGBATwoPlane(fmt Format) *kdf.Block {
	return block
}

var packedYUVAFormats = []Format{
	FormatYUYV,
	FormatYVYU,
	FormatUYVY,
	FormatVYUY,
	// TODO: AYUV and XYUV8888 have a single Y channel
	// TODO: VUY101010 has a single Y channel and is 10-bit
	// TODO: more formats
}

func parseYUVAPackedFormat(s string) (channels []kdf.Channel, bitsPerChannel []int) {
	yuvaChannelMap := map[rune]kdf.Channel{
		'Y': kdf.ChannelYUVSDA_Y,
		'U': kdf.ChannelYUVSDA_U,
		'V': kdf.ChannelYUVSDA_V,
		'A': kdf.ChannelYUVSDA_A,
		'X': unusedChannel,
	}

	if len(s) != 4 {
		return nil, nil
	}

	for _, c := range s {
		ch, ok := yuvaChannelMap[c]
		if !ok {
			return nil, nil
		}
		channels = append(channels, ch)
	}

	reverseChannels(channels)

	bitsPerChannel = []int{8, 8, 8, 8}

	return channels, bitsPerChannel
}

func genYUVAPacked(channels []kdf.Channel, bitsPerChannel []int) *kdf.Block {
	sampleInfo := genPackedSamples(channels, bitsPerChannel)
	numY := 0
	for i := len(sampleInfo) - 1; i >= 0; i-- {
		sample := &sampleInfo[i]
		if sample.Channel != kdf.ChannelYUVSDA_Y {
			continue
		}
		sample.SamplePosition[0] = uint8(numY * 0x80) // numY * 1.0
		numY++
	}

	return kdf.NewBlockBasic(&kdf.BlockBasic{
		ColorModel:          kdf.ColorModelYUVSDA,
		TexelBlockDimension: [4]int{2, 1, 1, 1},
		BytesPlane:          []uint8{getBytesPerPixel(bitsPerChannel)},
		SampleInfo:          sampleInfo,
	})
}

var blockTableOnce sync.Once
var blockTable map[Format]*kdf.Block



@@ 182,6 250,11 @@ func genTable() {
	for _, fmt := range twoPlaneRGBAFormats {
		blockTable[fmt] = genRGBATwoPlane(fmt)
	}

	for _, fmt := range packedYUVAFormats {
		channels, bitsPerChannel := parseYUVAPackedFormat(fmt.String())
		blockTable[fmt] = genYUVAPacked(channels, bitsPerChannel)
	}
}

func GetBlock(format Format) *kdf.Block {