Skip to content

Commit

Permalink
#511 add more diagnostics
Browse files Browse the repository at this point in the history
  • Loading branch information
totaam committed Jan 21, 2025
1 parent 1cb5e3a commit 49c40d6
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 33 deletions.
119 changes: 112 additions & 7 deletions xpra/codecs/amf/amf.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ cdef extern from "core/Data.h":
ctypedef AMF_MEMORY_TYPE (*DATA_GETMEMORYTYPE)(AMFData* pThis);
ctypedef AMF_DATA_TYPE (*DATA_GETDATATYPE)(AMFData* pThis);


ctypedef struct AMFDataVtbl:
DATA_ACQUIRE Acquire
DATA_RELEASE Release
Expand Down Expand Up @@ -267,6 +266,17 @@ cdef extern from "core/Buffer.h":
const AMFBufferVtbl *pVtbl


cdef inline AMF_PLANE_TYPE_STR(AMF_PLANE_TYPE ptype):
return {
AMF_PLANE_UNKNOWN: "UNKNOWN",
AMF_PLANE_PACKED: "PACKED",
AMF_PLANE_Y: "Y",
AMF_PLANE_UV: "UV",
AMF_PLANE_U: "U",
AMF_PLANE_V: "V",
}.get(ptype, "unknown")


cdef extern from "core/Trace.h":

ctypedef void (*TRACEW)(AMFTrace* pThis, const wchar_t* src_path, amf_int32 line, amf_int32 level, const wchar_t* scope,amf_int32 countArgs, const wchar_t* format, ...)
Expand All @@ -289,6 +299,37 @@ cdef extern from "core/Trace.h":


cdef extern from "core/Surface.h":
ctypedef enum AMF_FRAME_TYPE:
AMF_FRAME_STEREO_FLAG
AMF_FRAME_LEFT_FLAG
AMF_FRAME_RIGHT_FLAG
AMF_FRAME_BOTH_FLAG
AMF_FRAME_INTERLEAVED_FLAG
AMF_FRAME_FIELD_FLAG
AMF_FRAME_EVEN_FLAG
AMF_FRAME_ODD_FLAG

# values
AMF_FRAME_UNKNOWN
AMF_FRAME_PROGRESSIVE

AMF_FRAME_INTERLEAVED_EVEN_FIRST
AMF_FRAME_INTERLEAVED_ODD_FIRST
AMF_FRAME_FIELD_SINGLE_EVEN
AMF_FRAME_FIELD_SINGLE_ODD

AMF_FRAME_STEREO_LEFT
AMF_FRAME_STEREO_RIGHT
AMF_FRAME_STEREO_BOTH

AMF_FRAME_INTERLEAVED_EVEN_FIRST_STEREO_LEFT
AMF_FRAME_INTERLEAVED_EVEN_FIRST_STEREO_RIGHT
AMF_FRAME_INTERLEAVED_EVEN_FIRST_STEREO_BOTH

AMF_FRAME_INTERLEAVED_ODD_FIRST_STEREO_LEFT
AMF_FRAME_INTERLEAVED_ODD_FIRST_STEREO_RIGHT
AMF_FRAME_INTERLEAVED_ODD_FIRST_STEREO_BOTH

ctypedef enum AMF_SURFACE_FORMAT:
AMF_SURFACE_NV12 # 1 - planar 4:2:0 Y width x height + packed UV width/2 x height/2 - 8 bit per component
AMF_SURFACE_YV12 # 2 - planar 4:2:0 Y width x height + V width/2 x height/2 + U width/2 x height/2 - 8 bit per component
Expand All @@ -314,22 +355,85 @@ cdef extern from "core/Surface.h":
ctypedef AMF_RESULT (*SURFACE_SETPROPERTY)(AMFSurface* pThis, const wchar_t* name, AMFVariantStruct value)
ctypedef amf_long (*SURFACE_ACQUIRE)(AMFSurface* pThis)
ctypedef amf_long (*SURFACE_RELEASE)(AMFSurface* pThis)
ctypedef AMF_SURFACE_FORMAT (*SURFACE_GETFORMAT)(AMFSurface* pThis)
ctypedef amf_size (*SURFACE_GETPLANESCOUNT)(AMFSurface* pThis)
ctypedef AMFPlane* (*SURFACE_GETPLANEAT)(AMFSurface* pThis, amf_size index)
ctypedef AMFPlane* (*SURFACE_GETPLANE)(AMFSurface* pThis, AMF_PLANE_TYPE type)
ctypedef AMF_FRAME_TYPE (*SURFACE_GETFRAMETYPE)(AMFSurface* pThis)

ctypedef struct AMFSurfaceVtbl:
SURFACE_SETPROPERTY SetProperty
SURFACE_ACQUIRE Acquire
SURFACE_RELEASE Release
SURFACE_GETFORMAT GetFormat
SURFACE_GETPLANESCOUNT GetPlanesCount
SURFACE_GETPLANEAT GetPlaneAt
SURFACE_GETPLANE GetPlane
SURFACE_GETFRAMETYPE GetFrameType

ctypedef struct AMFSurface:
const AMFSurfaceVtbl *pVtbl


cdef inline AMF_SURFACE_FORMAT_STR(AMF_SURFACE_FORMAT fmt):
return {
AMF_SURFACE_NV12: "NV12",
AMF_SURFACE_YV12: "YV12",
AMF_SURFACE_BGRA: "BGRA",
AMF_SURFACE_ARGB: "ARGB",
AMF_SURFACE_RGBA: "RGBA",
AMF_SURFACE_GRAY8: "GRAY8",
AMF_SURFACE_YUV420P: "YUV420P",
AMF_SURFACE_U8V8: "U8V8",
AMF_SURFACE_YUY2: "YUY2",
AMF_SURFACE_P010: "P010",
AMF_SURFACE_RGBA_F16: "RGBA_F16",
AMF_SURFACE_UYVY: "UYVY",
AMF_SURFACE_R10G10B10A2: "R10G10B10A2",
AMF_SURFACE_Y210: "Y210",
AMF_SURFACE_AYUV: "AYUV",
AMF_SURFACE_Y410: "Y410",
AMF_SURFACE_Y416: "Y416",
AMF_SURFACE_GRAY32: "GRAY32",
AMF_SURFACE_P012: "P012",
AMF_SURFACE_P016: "P016",
}.get(fmt, "unknown")


cdef inline AMF_FRAME_TYPE_STR(AMF_FRAME_TYPE ftype):
return {
AMF_FRAME_STEREO_FLAG: "STEREO_FLAG",
AMF_FRAME_LEFT_FLAG: "LEFT_FLAG",
AMF_FRAME_RIGHT_FLAG: "RIGHT_FLAG",
AMF_FRAME_BOTH_FLAG: "BOTH_FLAG",
AMF_FRAME_INTERLEAVED_FLAG: "INTERLEAVED_FLAG",
AMF_FRAME_FIELD_FLAG: "FIELD_FLAG",
AMF_FRAME_EVEN_FLAG: "EVEN_FLAG",
AMF_FRAME_ODD_FLAG: "ODD_FLAG",

# values
AMF_FRAME_UNKNOWN: "UNKNOWN",
AMF_FRAME_PROGRESSIVE: "PROGRESSIVE",

AMF_FRAME_INTERLEAVED_EVEN_FIRST: "INTERLEAVED_EVEN_FIRST",
AMF_FRAME_INTERLEAVED_ODD_FIRST: "INTERLEAVED_ODD_FIRST",
AMF_FRAME_FIELD_SINGLE_EVEN: "FIELD_SINGLE_EVEN",
AMF_FRAME_FIELD_SINGLE_ODD: "FIELD_SINGLE_ODD",

AMF_FRAME_STEREO_LEFT: "STEREO_LEFT",
AMF_FRAME_STEREO_RIGHT: "STEREO_RIGHT",
AMF_FRAME_STEREO_BOTH: "STEREO_BOTH",

AMF_FRAME_INTERLEAVED_EVEN_FIRST_STEREO_LEFT: "INTERLEAVED_EVEN_FIRST_STEREO_LEFT",
AMF_FRAME_INTERLEAVED_EVEN_FIRST_STEREO_RIGHT: "INTERLEAVED_EVEN_FIRST_STEREO_RIGHT",
AMF_FRAME_INTERLEAVED_EVEN_FIRST_STEREO_BOTH: "INTERLEAVED_EVEN_FIRST_STEREO_BOTH",

AMF_FRAME_INTERLEAVED_ODD_FIRST_STEREO_LEFT: "INTERLEAVED_ODD_FIRST_STEREO_LEFT",
AMF_FRAME_INTERLEAVED_ODD_FIRST_STEREO_RIGHT: "INTERLEAVED_ODD_FIRST_STEREO_RIGHT",
AMF_FRAME_INTERLEAVED_ODD_FIRST_STEREO_BOTH: "INTERLEAVED_ODD_FIRST_STEREO_BOTH",
}.get(ftype, "unknown")


cdef extern from "core/Context.h":
ctypedef enum AMF_DX_VERSION:
AMF_DX9 # 90
Expand Down Expand Up @@ -538,12 +642,13 @@ cdef extern from "components/VideoEncoderVCE.h":
AMF_VIDEO_ENCODER_PICTURE_TYPE_B


OUTPUT_DATA_TYPES: Dict[int, str] = {
AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_IDR: "IDR",
AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_I: "I",
AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_P: "P",
AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_B: "B",
}
cdef inline AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_STR(AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_ENUM dtype):
return {
AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_IDR: "IDR",
AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_I: "I",
AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_P: "P",
AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_B: "B",
}.get(dtype, "unknown")


cdef extern from "components/VideoEncoderHEVC.h":
Expand Down
70 changes: 44 additions & 26 deletions xpra/codecs/amf/encoder.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ from xpra.util.env import envbool
from xpra.util.objects import typedict

from libc.stddef cimport wchar_t
from libc.stdint cimport uint8_t, uint64_t, uintptr_t
from libc.stdint cimport uint8_t, uint64_t, int64_t, uintptr_t
from libc.string cimport memset

from xpra.codecs.amf.amf cimport (
set_guid,
AMF_PLANE_TYPE_STR, AMF_SURFACE_FORMAT_STR, AMF_FRAME_TYPE_STR,
AMF_RESULT, AMF_EOF, AMF_REPEAT,
AMF_DX11_0,
AMF_MEMORY_TYPE,
Expand All @@ -51,12 +52,12 @@ from xpra.codecs.amf.amf cimport (
AMFGuid,
AMFBuffer,
AMFComponentOptimizationCallback,
AMFPlane,
AMFData,
AMFPlane, AMFPlaneVtbl,
AMFData, AMFDataVtbl,
AMFTrace,
AMFVariantStruct,
AMFVariantAssignInt64,
AMFSurface,
AMFSurface, AMFSurfaceVtbl,
AMFContext,
AMFComponent,
AMFFactory,
Expand Down Expand Up @@ -264,7 +265,7 @@ cdef class Encoder:
self.amf_surface_init()
self.amf_encoder_init(options)

if SAVE_TO_FILE is not None:
if SAVE_TO_FILE:
filename = SAVE_TO_FILE+f"amf-{self.generation}.{encoding}"
self.file = open(filename, "wb")
log.info(f"saving {encoding} stream to {filename!r}")
Expand Down Expand Up @@ -458,7 +459,6 @@ cdef class Encoder:
def compress_image(self, image: ImageWrapper, options: typedict) -> Tuple[bytes, Dict]:
cdef uint8_t *pic_in[2]
cdef int strides[2]
cdef int sizes[2]
assert self.context!=NULL
pixels = image.get_pixels()
istrides = image.get_rowstride()
Expand Down Expand Up @@ -493,8 +493,7 @@ cdef class Encoder:
py_buf[i].len, "YUV"[i], istrides[i]*(self.height//ydiv))
pic_in[i] = <uint8_t *> py_buf[i].buf
strides[i] = istrides[i]
sizes[i] = istrides[i] * (self.height // ydiv)
return self.do_compress_image(pic_in, strides, sizes), {
return self.do_compress_image(pic_in, strides), {
"csc" : self.src_format,
"frame" : int(self.frames),
"full-range" : bool(full_range),
Expand All @@ -513,7 +512,7 @@ cdef class Encoder:
self.surface.pVtbl.SetProperty(self.surface, prop, var)
PyMem_Free(prop)

cdef bytes do_compress_image(self, uint8_t *pic_in[2], int strides[2], int sizes[2]):
cdef bytes do_compress_image(self, uint8_t *pic_in[2], int strides[2]):
cdef unsigned long start_time = 0 # nanoseconds!
cdef AMFPlane *plane
cdef uintptr_t dst_texture
Expand All @@ -527,6 +526,7 @@ cdef class Encoder:
with device.get_device_context() as dc:
log("device: %s", device.get_info())
log("device context: %s", dc.get_info())
log("surface: %s", self.get_surface_info(self.surface))
for plane_index in range(2):
# get the D3D11 destination surface pointer for this plane:
plane = self.surface.pVtbl.GetPlaneAt(self.surface, plane_index)
Expand All @@ -536,9 +536,8 @@ cdef class Encoder:
dst_texture = <uintptr_t> plane.pVtbl.GetNative(plane)
log("texture=%#x, source=%#x", dst_texture, <uintptr_t> pic_in[plane_index])
assert dst_texture
box = ()
#dc.update_subresource(dst_texture, 0, box,
# <uintptr_t> pic_in[plane_index], strides[plane_index], sizes[plane_index])
#dc.update_2dtexture(dst_texture, self.width, self.height,
# <uintptr_t> pic_in[plane_index], strides[plane_index])
dc.flush()

ns = round(1000 * 1000 * monotonic())
Expand Down Expand Up @@ -577,12 +576,14 @@ cdef class Encoder:
size = buffer.pVtbl.GetSize(buffer)
log(f"output=%#x, size=%i", <uintptr_t> output, size)
assert output and size
return output[:size]
bdata = output[:size]
if self.file:
self.file.write(bdata)
return bdata
finally:
if buffer != NULL:
buffer.pVtbl.Release(buffer)
data.pVtbl.Release(data)
return b""

def flush(self, unsigned long frame_no) -> None:
cdef AMF_RESULT res = self.encoder.pVtbl.Drain(self.encoder)
Expand All @@ -593,23 +594,40 @@ cdef class Encoder:
self.check(res, "AMF encoder flush")

cdef get_data_info(self, AMFData *data):
assert data
cdef const AMFDataVtbl *dfn = data.pVtbl
return {
"property-count": data.pVtbl.GetPropertyCount(data),
"memory-type": data.pVtbl.GetMemoryType(data),
"data-type": data.pVtbl.GetDataType(data),
"property-count": dfn.GetPropertyCount(data),
"memory-type": dfn.GetMemoryType(data),
"data-type": dfn.GetDataType(data),
}

cdef get_plane_info(self, AMFPlane *plane):
assert plane
ptype = plane.pVtbl.GetType(plane)
cdef const AMFPlaneVtbl *pfn = plane.pVtbl
return {
"type": AMF_PLANE_TYPE_STR(ptype),
"native": <uintptr_t> pfn.GetNative(plane),
"size": pfn.GetPixelSizeInBytes(plane),
"offset-x": pfn.GetOffsetX(plane),
"offset-y": pfn.GetOffsetY(plane),
"width": pfn.GetWidth(plane),
"height": pfn.GetHeight(plane),
"h-pitch": pfn.GetHPitch(plane),
"v-pitch": pfn.GetVPitch(plane),
"is-tiled": pfn.IsTiled(plane),
}

cdef get_surface_info(self, AMFSurface *surface):
assert surface
cdef const AMFSurfaceVtbl *sfn = surface.pVtbl
fmt = sfn.GetFormat(surface)
ftype = sfn.GetFrameType(surface)
return {
"native": <uintptr_t> plane.pVtbl.GetNative(plane),
"size": plane.pVtbl.GetPixelSizeInBytes(plane),
"offset-x": plane.pVtbl.GetOffsetX(plane),
"offset-y": plane.pVtbl.GetOffsetY(plane),
"width": plane.pVtbl.GetWidth(plane),
"height": plane.pVtbl.GetHeight(plane),
"h-pitch": plane.pVtbl.GetHPitch(plane),
"v-pitch": plane.pVtbl.GetVPitch(plane),
"is-tiled": plane.pVtbl.IsTiled(plane),
"format": AMF_SURFACE_FORMAT_STR(fmt),
"planes": sfn.GetPlanesCount(surface),
"frame-type": AMF_FRAME_TYPE_STR(ftype),
}

def set_encoding_speed(self, int pct) -> None:
Expand Down

0 comments on commit 49c40d6

Please sign in to comment.