Hash :
bda75597
Author :
Date :
2016-04-18T17:25:54
Finish NV12 support via streams. The main functionality for NV12 texture support through EGL streams has been added. Updates to the compiler, texture code, and stream code were added to support binding to external D3D11 NV12 textures. An end2end test was also added to test sampling of YUV textures and converting to RGB. There is also a new script to convert BMP files to an NV12 texture ready to load into D3D11 for testing purposes. BUG=angleproject:1332 Change-Id: I39b6ec393ea338e2c843fb911acc1b36cd1158a0 Reviewed-on: https://chromium-review.googlesource.com/339454 Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Ian Ewell <ewell@google.com> Reviewed-on: https://chromium-review.googlesource.com/341254 Reviewed-by: Ian Ewell <ewell@google.com>
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
#!/usr/bin/python
#
# Copyright 2016 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# bmp_to_nv12.py:
# Script to convert a simple BMP file to an NV12 format. Used to create
# test images for the NV12 texture stream end to end tests
import sys
import struct
if len(sys.argv) != 4:
print("Usage: bmp_to_nv12.py input output prefix")
exit(0)
bmp_file = open(sys.argv[1], "rb")
magic = bmp_file.read(2)
if (magic != "BM"):
print("Invalid BMP magic")
exit(1)
file_size, = struct.unpack("I", bmp_file.read(4))
# eat reserved bytes
bmp_file.read(4)
offset, = struct.unpack("I", bmp_file.read(4))
headersize, = struct.unpack("I", bmp_file.read(4))
width, = struct.unpack("i", bmp_file.read(4))
height, = struct.unpack("i", bmp_file.read(4))
planes, = struct.unpack("H", bmp_file.read(2))
bpp, = struct.unpack("H", bmp_file.read(2))
compression, = struct.unpack("i", bmp_file.read(4))
image_size, = struct.unpack("i", bmp_file.read(4))
if (bpp != 24 or compression != 0):
print("Unsupported BMP file")
bmp_file.close()
exit(1)
bmp_file.seek(offset, 0)
pixels = bmp_file.read(width * height * 3)
bmp_file.close()
# convert to YUV 4:4:4
converted_pixels = bytearray(pixels)
for i in range(0, width * height):
R, = struct.unpack("B", pixels[i*3+2])
G, = struct.unpack("B", pixels[i*3+1])
B, = struct.unpack("B", pixels[i*3])
converted_pixels[i*3] = ((66*R + 129*G + 25*B + 128) >> 8) + 16
converted_pixels[i*3+1] = ((-38*R - 74*G + 112*B + 128) >> 8) + 128
converted_pixels[i*3+2] = ((112*R - 94*G - 18*B + 128) >> 8) + 128
# downsample to packed UV buffer
uv_buffer = bytearray(width * height / 2)
for i in range(0, width * height / 2, 2):
U1 = converted_pixels[((((i / width) * 2) * width) + (i % width)) * 3 + 1]
U2 = converted_pixels[((((i / width) * 2) * width) + width + (i % width)) * 3 + 1]
V1 = converted_pixels[((((i / width) * 2) * width) + (i % width)) * 3 + 2]
V2 = converted_pixels[((((i / width) * 2) * width) + width + (i % width)) * 3 + 2]
uv_buffer[i] = (U1 + U2) / 2
uv_buffer[i + 1] = (V1 + V2) / 2
# extract the Y buffer
y_buffer = bytearray(width * height)
for i in range(0, width * height):
y_buffer[i] = converted_pixels[i * 3]
# write out the file as a C header
nv12_file = open(sys.argv[2], "w")
nv12_file.write("// Automatically generated from " + sys.argv[1] + "\n")
nv12_file.write("static const size_t " + sys.argv[3] + "_width = " + str(width) + ";\n")
nv12_file.write("static const size_t " + sys.argv[3] + "_height = " + str(height) + ";\n")
nv12_file.write("static const unsigned char " + sys.argv[3] + "_data[] = \n{")
for i in range(0, width * height):
if (i % 16) == 0:
nv12_file.write("\n ")
nv12_file.write(str(y_buffer[i]) + ",")
for i in range(0, width * height / 2):
if (i % 16) == 0:
nv12_file.write("\n ")
nv12_file.write(str(uv_buffer[i]) + ",")
nv12_file.write("\n};")
nv12_file.close()