mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 16:26:39 +00:00
162 lines
4.7 KiB
Python
Executable file
162 lines
4.7 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
import argparse
|
|
import gi
|
|
import os
|
|
import sys
|
|
|
|
gi.require_version("Gst", "1.0")
|
|
gi.require_version("GstVideo", "1.0")
|
|
|
|
from gi.repository import GLib
|
|
from gi.repository import Gst, GstVideo
|
|
|
|
|
|
def video_format_exists(f):
|
|
return GstVideo.video_format_from_string(f) != GstVideo.VideoFormat.UNKNOWN
|
|
|
|
|
|
def video_format_info_from_string(s):
|
|
f = GstVideo.video_format_from_string(s)
|
|
return GstVideo.video_format_get_info(f)
|
|
|
|
|
|
def parse_format_from_c(token, filename):
|
|
code = open(filename).read().splitlines()
|
|
token_found = False
|
|
formats = None
|
|
|
|
for idx, line in enumerate(code):
|
|
if formats is None:
|
|
match = f"#define {token}"
|
|
if line.startswith(match):
|
|
formats = []
|
|
line = line[len(match):]
|
|
else:
|
|
continue
|
|
|
|
tmp = line.replace("\\", "")\
|
|
.replace("\"", "")\
|
|
.replace(",", " ")\
|
|
.replace("{", " ")\
|
|
.replace("}", " ")\
|
|
.split()
|
|
for f in tmp:
|
|
if not video_format_exists(f):
|
|
basename = os.path.basename(filename)
|
|
print(f"WARNING: {basename}:{idx}: unknown format {f}")
|
|
|
|
formats += tmp
|
|
|
|
if line[-1] != "\\":
|
|
break
|
|
|
|
if formats is None:
|
|
print(f"Define for {token} not found in {filename}")
|
|
return None
|
|
|
|
formats = list(filter(video_format_exists, formats))
|
|
|
|
return [video_format_info_from_string(f) for f in formats]
|
|
|
|
|
|
def score_endian(fmt, endian):
|
|
native_endianness = [GstVideo.VideoFormat.ARGB64, GstVideo.VideoFormat.AYUV64]
|
|
if fmt.format in native_endianness:
|
|
return -1
|
|
|
|
score = 0
|
|
if fmt.flags & GstVideo.VideoFormatFlags.LE:
|
|
score = 1
|
|
if endian == "LE":
|
|
return -score
|
|
else:
|
|
return score
|
|
|
|
|
|
def score_pixel_stride(fmt):
|
|
# Prefer power-of-two strides over odd ones, e.g. xRGB over RGB
|
|
def scale_non_power_of_two(x):
|
|
if (x & (x - 1) == 0) and x != 0:
|
|
return x
|
|
else:
|
|
return x * 100
|
|
|
|
return [scale_non_power_of_two(x) for x in fmt.pixel_stride]
|
|
|
|
|
|
def sort_video_formats(formats, endian):
|
|
return sorted(formats, key=lambda x: (-x.n_components,
|
|
[-d for d in x.depth],
|
|
x.w_sub,
|
|
x.h_sub,
|
|
-x.n_planes,
|
|
score_endian(x, endian),
|
|
(x.flags & GstVideo.VideoFormatFlags.COMPLEX),
|
|
not (x.flags & GstVideo.VideoFormatFlags.YUV),
|
|
score_pixel_stride(x),
|
|
[s for s in x.pixel_stride],
|
|
[o for o in x.poffset],
|
|
x.name))
|
|
|
|
|
|
def video_formats_to_c(token, formats, bracket):
|
|
s = [f'#define {token} "']
|
|
|
|
if bracket:
|
|
s[-1] += "{ "
|
|
|
|
for f in formats:
|
|
if len(s[-1]) > 80 - len(f.name) - len(', " \\'):
|
|
s[-1] += ', " \\'
|
|
s.append(' "')
|
|
if s[-1][-2:] not in (' "', '{ '):
|
|
s[-1] += ", "
|
|
s[-1] += f.name
|
|
|
|
if bracket:
|
|
s[-1] += " }"
|
|
|
|
s[-1] += '"'
|
|
return s
|
|
|
|
|
|
def generate_c_code(token, formats_be, formats_le, bracket):
|
|
s = ["#if G_BYTE_ORDER == G_BIG_ENDIAN"]
|
|
s += video_formats_to_c(token, formats_be, bracket)
|
|
s += ["#elif G_BYTE_ORDER == G_LITTLE_ENDIAN"]
|
|
s += video_formats_to_c(token, formats_le, bracket)
|
|
s += ["#endif"]
|
|
return s
|
|
|
|
|
|
def main(args):
|
|
formats = parse_format_from_c(args.token, args.filename)
|
|
if formats is None:
|
|
return 1
|
|
|
|
formats_be = sort_video_formats(formats, "BE")
|
|
formats_le = sort_video_formats(formats, "LE")
|
|
|
|
# We only check BE order as the list are now generated
|
|
if formats_be == formats:
|
|
print("Formats are properly ordered.")
|
|
return 0
|
|
|
|
basename = os.path.basename(args.filename)
|
|
print(f"ERROR: Formats order differ for {args.token} in {args.filename}")
|
|
print("This can be fixed by replacing the define with:\n")
|
|
for c_line in generate_c_code(args.token, formats_be, formats_le,
|
|
args.bracket):
|
|
print(c_line)
|
|
return 1
|
|
|
|
|
|
if __name__ == '__main__':
|
|
Gst.init(None)
|
|
parser = argparse.ArgumentParser(prog='sort_video_formats',
|
|
description='Sort video formats list')
|
|
parser.add_argument('token')
|
|
parser.add_argument('filename')
|
|
parser.add_argument('-b', '--bracket', action='store_true')
|
|
args = parser.parse_args()
|
|
sys.exit(main(args))
|