Skip to content

Commit

Permalink
Fork gst-d3d11 to gst-d3d12 support
Browse files Browse the repository at this point in the history
Signed-off-by: Wu, Bin1 <[email protected]>
  • Loading branch information
Bin-CI authored and uartie committed Jun 3, 2024
1 parent ff4ef41 commit 730bbf6
Show file tree
Hide file tree
Showing 19 changed files with 575 additions and 0 deletions.
5 changes: 5 additions & 0 deletions lib/gstreamer/d3d12/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
###
### Copyright (C) 2024 Intel Corporation
###
### SPDX-License-Identifier: BSD-3-Clause
###
89 changes: 89 additions & 0 deletions lib/gstreamer/d3d12/decoder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
###
### Copyright (C) 2024 Intel Corporation
###
### SPDX-License-Identifier: BSD-3-Clause
###

import os
import slash

from ....lib import platform
from ....lib.codecs import Codec
from ....lib.common import get_media
from ....lib.formats import PixelFormat
from ....lib.gstreamer.decoderbase import BaseDecoderTest, Decoder as GstDecoder
from ....lib.gstreamer.util import have_gst_element
from ....lib.gstreamer.d3d12.util import mapformat, mapformatu

class Decoder(GstDecoder):
format = property(lambda s: mapformatu(super().format))
pformat = property(lambda s: mapformat(super().format))

@slash.requires(*have_gst_element("d3d12"))
class DecoderTest(BaseDecoderTest):
DecoderClass = Decoder

def decode_test_class(codec, bitdepth, **kwargs):
# caps lookup translation
capcodec = codec
if codec in [Codec.HEVC, Codec.VP9, Codec.AV1]:
capcodec = f"{codec}_{bitdepth}"

# gst element codec translation
gstcodec = {
Codec.AVC : "h264",
Codec.HEVC : "h265",
}.get(codec, codec)

gstparser = {
Codec.MPEG2 : "mpegvideoparse",
Codec.VP8 : None,
}.get(codec, f"{gstcodec}parse")

hwdevice = get_media().render_device.split('/')[-1]
hw = hwdevice if hwdevice not in ['renderD128', '0'] else ""

@slash.requires(*have_gst_element(f"d3d12{hw}{gstcodec}dec"))
@slash.requires(*platform.have_caps("decode", capcodec))
class CodecDecoderTest(DecoderTest):
def before(self):
super().before()
vars(self).update(
caps = platform.get_caps("decode", capcodec),
codec = codec,
gstdecoder = f"d3d12{hw}{gstcodec}dec",
gstparser = gstparser,
**kwargs,
)

def validate_caps(self):
assert PixelFormat(self.format).bitdepth == bitdepth
super().validate_caps()

return CodecDecoderTest

## AVC ##
AVCDecoderTest = decode_test_class(codec = Codec.AVC, bitdepth = 8)

## HEVC ##
HEVC_8DecoderTest = decode_test_class(codec = Codec.HEVC, bitdepth = 8)
HEVC_10DecoderTest = decode_test_class(codec = Codec.HEVC, bitdepth = 10)
HEVC_12DecoderTest = decode_test_class(codec = Codec.HEVC, bitdepth = 12)

## AV1 ##
AV1_8DecoderTest = decode_test_class(codec = Codec.AV1, bitdepth = 8)
AV1_10DecoderTest = decode_test_class(codec = Codec.AV1, bitdepth = 10)

## VP9 ##
VP9_8DecoderTest = decode_test_class(codec = Codec.VP9, bitdepth = 8)
VP9_10DecoderTest = decode_test_class(codec = Codec.VP9, bitdepth = 10)
VP9_12DecoderTest = decode_test_class(codec = Codec.VP9, bitdepth = 12)

## VP8 ##
VP8DecoderTest = decode_test_class(codec = Codec.VP8, bitdepth = 8)

## JPEG/MJPEG ##
JPEGDecoderTest = decode_test_class(codec = Codec.JPEG, bitdepth = 8)

## MPEG2 ##
MPEG2DecoderTest = decode_test_class(codec = Codec.MPEG2, bitdepth = 8)
96 changes: 96 additions & 0 deletions lib/gstreamer/d3d12/util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
###
### Copyright (C) 2024 Intel Corporation
###
### SPDX-License-Identifier: BSD-3-Clause
###

from ....lib.codecs import Codec
from ....lib.common import memoize
from ....lib.formats import match_best_format
from ....lib.gstreamer.util import *

def get_supported_format_map():
#The map first entry is for gst element properties;the second entry is for gst caps filters
#for example:
# i420 is entry for gst properties such as vaapipostproc
# I420: is entry for gst caps filter
return {
"I420" : ("i420", "I420"),
"NV12" : ("nv12", "NV12"),
"YV12" : ("yv12", "YV12"),
"AYUV" : ("vuya", "VUYA"), #we use microsoft's definition of AYUV,https://docs.microsoft.com/en-us/windows/win32/medfound/recommended-8-bit-yuv-formats-for-video-rendering#ayuv
"YUY2" : ("yuy2", "YUY2"),
"ARGB" : ("argb", "ARGB"),
"BGRA" : ("bgra", "BGRA"),
"422H" : ("y42b", "Y42B"),
"444P" : ("y444", "Y444"),
"P010" : ("p010-10le", "P010_10LE"),
"P012" : ("p012-le", "P012_LE"),
"I010" : ("i420-10le", "I420_10LE"),
"Y210" : ("y210", "Y210"),
"Y212" : ("y212-le", "Y212_LE"),
"Y410" : ("y410", "Y410"),
"Y412" : ("y412-le", "Y412_LE"),
}

@memoize
def mapformat(format):
return get_supported_format_map().get(format, (None, None))[0]

@memoize
def mapformatu(format):
return get_supported_format_map().get(format, (None, None))[1]

def map_best_hw_format(format, hwformats):
return mapformatu(
match_best_format(
format, set(hwformats) & set(get_supported_format_map().keys())))

@memoize
def map_transpose_direction(degrees, method):
return {
( 0, None) : "identity",
( 0, "vertical") : "vert",
( 0, "horizontal") : "horiz",
( 90, None) : "90r",
( 90, "vertical") : "ur-ll",
( 90, "horizontal") : "ul-lr",
(180, None) : "180",
(180, "vertical") : "horiz",
(180, "horizontal") : "vert",
(270, None) : "90l",
(270, "vertical") : "ul-lr",
(270, "horizontal") : "ur-ll",
}.get((degrees, method), None)

@memoize
def mapprofile(codec, profile):
return {
Codec.AVC : {
"high" : "high",
"main" : "main",
"baseline" : "baseline",
"constrained-baseline" : "constrained-baseline",
"multiview-high" : "multiview-high",
"stereo-high" : "stereo-high",
},
Codec.HEVC : {
"main" : "main",
"scc" : "screen-extended-main",
"scc-444" : "screen-extended-main-444",
"main444" : "main-444",
#profile of "hevc-8bit 422" is mapped to main-422-10 based on
#https://en.wikipedia.org/wiki/High_Efficiency_Video_Coding#Profiles
"main422" : "main-422-10",
"main10" : "main-10",
"main444-10" : "main-444-10",
"main12" : "main-12",
},
Codec.VP9 : {
"profile3" : "profile3",
},
}.get(codec, {}).get(profile, None)

def load_test_spec(*ctx):
from ....lib import util as libutil
return libutil.load_test_spec("gst-d3d12", *ctx)
5 changes: 5 additions & 0 deletions test/gst-d3d12/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
###
### Copyright (C) 2024 Intel Corporation
###
### SPDX-License-Identifier: BSD-3-Clause
###
5 changes: 5 additions & 0 deletions test/gst-d3d12/decode/10bit/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
###
### Copyright (C) 2024 Intel Corporation
###
### SPDX-License-Identifier: BSD-3-Clause
###
34 changes: 34 additions & 0 deletions test/gst-d3d12/decode/10bit/av1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
###
### Copyright (C) 2024 Intel Corporation
###
### SPDX-License-Identifier: BSD-3-Clause
###

from .....lib import *
from .....lib.gstreamer.d3d12.util import *
from .....lib.gstreamer.d3d12.decoder import AV1_10DecoderTest as DecoderTest

spec = load_test_spec("av1", "decode", "10bit")

class default(DecoderTest):
def before(self):
super().before()
vars(self).update(
# default metric
metric = dict(type = "ssim", miny = 1.0, minu = 1.0, minv = 1.0),
)

@slash.parametrize(("case"), sorted(spec.keys()))
def test(self, case):
vars(self).update(spec[case].copy())

dxmap = {".ivf" : "ivfparse", ".webm" : "matroskademux", ".mkv" : "matroskademux", ".obu" : "av1parse"}
ext = os.path.splitext(self.source)[1]
dx = dxmap.get(ext, None)
assert dx is not None, "Unrecognized source file extension {}".format(ext)

vars(self).update(
case = case,
gstdemuxer = dx if self.gstparser not in dx else None,
)
self.decode()
25 changes: 25 additions & 0 deletions test/gst-d3d12/decode/10bit/hevc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
###
### Copyright (C) 2024 Intel Corporation
###
### SPDX-License-Identifier: BSD-3-Clause
###

from .....lib import *
from .....lib.gstreamer.d3d12.util import *
from .....lib.gstreamer.d3d12.decoder import HEVC_10DecoderTest as DecoderTest

spec = load_test_spec("hevc", "decode", "10bit")

class default(DecoderTest):
def before(self):
super().before()
vars(self).update(
# default metric
metric = dict(type = "ssim", miny = 1.0, minu = 1.0, minv = 1.0),
)

@slash.parametrize(("case"), sorted(spec.keys()))
def test(self, case):
vars(self).update(spec[case].copy())
vars(self).update(case = case)
self.decode()
33 changes: 33 additions & 0 deletions test/gst-d3d12/decode/10bit/vp9.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
###
### Copyright (C) 2024 Intel Corporation
###
### SPDX-License-Identifier: BSD-3-Clause
###

from .....lib import *
from .....lib.gstreamer.d3d12.util import *
from .....lib.gstreamer.d3d12.decoder import VP9_10DecoderTest as DecoderTest

spec = load_test_spec("vp9", "decode", "10bit")

class default(DecoderTest):
def before(self):
super().before()
vars(self).update(
# default metric
metric = dict(type = "ssim", miny = 1.0, minu = 1.0, minv = 1.0),
)

@slash.parametrize(("case"), sorted(spec.keys()))
def test(self, case):
vars(self).update(spec[case].copy())

dxmap = {".ivf" : "ivfparse", ".webm" : "matroskademux", ".mkv" : "matroskademux"}
ext = os.path.splitext(self.source)[1]
assert ext in dxmap.keys(), "Unrecognized source file extension {}".format(ext)

vars(self).update(
case = case,
gstdemuxer = dxmap[ext],
)
self.decode()
5 changes: 5 additions & 0 deletions test/gst-d3d12/decode/12bit/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
###
### Copyright (C) 2024 Intel Corporation
###
### SPDX-License-Identifier: BSD-3-Clause
###
25 changes: 25 additions & 0 deletions test/gst-d3d12/decode/12bit/hevc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
###
### Copyright (C) 2024 Intel Corporation
###
### SPDX-License-Identifier: BSD-3-Clause
###

from .....lib import *
from .....lib.gstreamer.d3d12.util import *
from .....lib.gstreamer.d3d12.decoder import HEVC_12DecoderTest as DecoderTest

spec = load_test_spec("hevc", "decode", "12bit")

class default(DecoderTest):
def before(self):
super().before()
vars(self).update(
# default metric
metric = dict(type = "ssim", miny = 1.0, minu = 1.0, minv = 1.0),
)

@slash.parametrize(("case"), sorted(spec.keys()))
def test(self, case):
vars(self).update(spec[case].copy())
vars(self).update(case = case)
self.decode()
33 changes: 33 additions & 0 deletions test/gst-d3d12/decode/12bit/vp9.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
###
### Copyright (C) 2024 Intel Corporation
###
### SPDX-License-Identifier: BSD-3-Clause
###

from .....lib import *
from .....lib.gstreamer.d3d12.util import *
from .....lib.gstreamer.d3d12.decoder import VP9_12DecoderTest as DecoderTest

spec = load_test_spec("vp9", "decode", "12bit")

class default(DecoderTest):
def before(self):
super().before()
vars(self).update(
# default metric
metric = dict(type = "ssim", miny = 1.0, minu = 1.0, minv = 1.0),
)

@slash.parametrize(("case"), sorted(spec.keys()))
def test(self, case):
vars(self).update(spec[case].copy())

dxmap = {".ivf" : "ivfparse", ".webm" : "matroskademux", ".mkv" : "matroskademux"}
ext = os.path.splitext(self.source)[1]
assert ext in dxmap.keys(), "Unrecognized source file extension {}".format(ext)

vars(self).update(
case = case,
gstdemuxer = dxmap[ext],
)
self.decode()
5 changes: 5 additions & 0 deletions test/gst-d3d12/decode/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
###
### Copyright (C) 2024 Intel Corporation
###
### SPDX-License-Identifier: BSD-3-Clause
###
Loading

0 comments on commit 730bbf6

Please sign in to comment.