mirror of
https://github.com/koush/scrypted.git
synced 2026-05-04 21:30:30 +01:00
fix per frame rpc gc churn
This commit is contained in:
14
plugins/python-codecs/src/generator_common.py
Normal file
14
plugins/python-codecs/src/generator_common.py
Normal file
@@ -0,0 +1,14 @@
|
||||
import scrypted_sdk
|
||||
import time
|
||||
|
||||
async def flush():
|
||||
pass
|
||||
|
||||
def createVideoFrame(image) -> scrypted_sdk.VideoFrame:
|
||||
return {
|
||||
'__json_copy_serialize_children': True,
|
||||
'image': image,
|
||||
'queued': 0,
|
||||
'timestamp': time.time() * 1000,
|
||||
'flush': flush,
|
||||
}
|
||||
@@ -6,6 +6,7 @@ from urllib.parse import urlparse
|
||||
import vipsimage
|
||||
import pilimage
|
||||
import platform
|
||||
from generator_common import createVideoFrame
|
||||
|
||||
Gst = None
|
||||
try:
|
||||
@@ -87,6 +88,11 @@ async def generateVideoFramesGstreamer(mediaObject: scrypted_sdk.MediaObject, op
|
||||
videosrc += ' ! {decoder} ! queue leaky=downstream max-size-buffers=0 ! videoconvert ! {videorate} {videocaps}'.format(decoder=decoder, videocaps=videocaps, videorate=videorate)
|
||||
|
||||
gst, gen = await createPipelineIterator(videosrc)
|
||||
|
||||
vipsImage: vipsimage.VipsImage = None
|
||||
pilImage: pilimage.PILImage = None
|
||||
mo: scrypted_sdk.MediaObject = None
|
||||
|
||||
async for gstsample in gen():
|
||||
caps = gstsample.get_caps()
|
||||
height = caps.get_structure(0).get_value('height')
|
||||
@@ -99,19 +105,27 @@ async def generateVideoFramesGstreamer(mediaObject: scrypted_sdk.MediaObject, op
|
||||
try:
|
||||
if vipsimage.pyvips:
|
||||
vips = vipsimage.new_from_memory(info.data, width, height, bands)
|
||||
vipsImage = vipsimage.VipsImage(vips)
|
||||
try:
|
||||
|
||||
if not mo:
|
||||
vipsImage = vipsimage.VipsImage(vips)
|
||||
mo = await vipsimage.createVipsMediaObject(vipsImage)
|
||||
yield mo
|
||||
|
||||
vipsImage.vipsImage = vips
|
||||
try:
|
||||
yield createVideoFrame(mo)
|
||||
finally:
|
||||
vipsImage.vipsImage = None
|
||||
vips.invalidate()
|
||||
else:
|
||||
pil = pilimage.new_from_memory(info.data, width, height, bands)
|
||||
pilImage = pilimage.PILImage(pil)
|
||||
try:
|
||||
|
||||
if not mo:
|
||||
pilImage = pilimage.PILImage(pil)
|
||||
mo = await pilimage.createPILMediaObject(pilImage)
|
||||
yield mo
|
||||
|
||||
pilImage.pilImage = pil
|
||||
try:
|
||||
yield createVideoFrame(mo)
|
||||
finally:
|
||||
pilImage.pilImage = None
|
||||
pil.close()
|
||||
|
||||
@@ -3,6 +3,7 @@ import scrypted_sdk
|
||||
from typing import Any
|
||||
import vipsimage
|
||||
import pilimage
|
||||
from generator_common import createVideoFrame
|
||||
|
||||
av = None
|
||||
try:
|
||||
@@ -30,6 +31,10 @@ async def generateVideoFramesLibav(mediaObject: scrypted_sdk.MediaObject, option
|
||||
|
||||
start = 0
|
||||
try:
|
||||
vipsImage: vipsimage.VipsImage = None
|
||||
pilImage: pilimage.PILImage = None
|
||||
mo: scrypted_sdk.MediaObject = None
|
||||
|
||||
for idx, frame in enumerate(container.decode(stream)):
|
||||
now = time.time()
|
||||
if not start:
|
||||
@@ -46,10 +51,14 @@ async def generateVideoFramesLibav(mediaObject: scrypted_sdk.MediaObject, option
|
||||
vips = vipsimage.pyvips.Image.new_from_array(frame.to_ndarray(format='gray'))
|
||||
else:
|
||||
vips = vipsimage.pyvips.Image.new_from_array(frame.to_ndarray(format='rgb24'))
|
||||
vipsImage = vipsimage.VipsImage(vips)
|
||||
try:
|
||||
|
||||
if not mo:
|
||||
vipsImage = vipsimage.VipsImage(vips)
|
||||
mo = await vipsimage.createVipsMediaObject(vipsImage)
|
||||
yield mo
|
||||
|
||||
vipsImage.vipsImage = vips
|
||||
try:
|
||||
yield createVideoFrame(mo)
|
||||
finally:
|
||||
vipsImage.vipsImage = None
|
||||
vips.invalidate()
|
||||
@@ -64,10 +73,14 @@ async def generateVideoFramesLibav(mediaObject: scrypted_sdk.MediaObject, option
|
||||
rgb.close()
|
||||
else:
|
||||
pil = frame.to_image()
|
||||
pilImage = pilimage.PILImage(pil)
|
||||
try:
|
||||
|
||||
if not mo:
|
||||
pilImage = pilimage.PILImage(pil)
|
||||
mo = await pilimage.createPILMediaObject(pilImage)
|
||||
yield mo
|
||||
|
||||
pilImage.pilImage = pil
|
||||
try:
|
||||
yield createVideoFrame(mo)
|
||||
finally:
|
||||
pilImage.pilImage = None
|
||||
pil.close()
|
||||
|
||||
@@ -2,7 +2,6 @@ import scrypted_sdk
|
||||
from typing import Any
|
||||
from thread import to_thread
|
||||
import io
|
||||
import time
|
||||
|
||||
try:
|
||||
from PIL import Image
|
||||
@@ -10,7 +9,7 @@ except:
|
||||
# Image = None
|
||||
pass
|
||||
|
||||
class PILImage(scrypted_sdk.VideoFrame):
|
||||
class PILImage(scrypted_sdk.Image):
|
||||
def __init__(self, pilImage: Image.Image) -> None:
|
||||
super().__init__()
|
||||
self.pilImage = pilImage
|
||||
@@ -91,7 +90,6 @@ def toPILImage(pilImageWrapper: PILImage, options: scrypted_sdk.ImageOptions = N
|
||||
|
||||
async def createPILMediaObject(image: PILImage):
|
||||
ret = await scrypted_sdk.mediaManager.createMediaObject(image, scrypted_sdk.ScryptedMimeTypes.Image.value, {
|
||||
'timestamp': time.time() * 1000,
|
||||
'format': None,
|
||||
'width': image.width,
|
||||
'height': image.height,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import scrypted_sdk
|
||||
import asyncio
|
||||
from typing import Any
|
||||
try:
|
||||
import pyvips
|
||||
@@ -7,9 +8,8 @@ except:
|
||||
Image = None
|
||||
pyvips = None
|
||||
from thread import to_thread
|
||||
import time
|
||||
|
||||
class VipsImage(scrypted_sdk.VideoFrame):
|
||||
class VipsImage(scrypted_sdk.Image):
|
||||
def __init__(self, vipsImage: Image) -> None:
|
||||
super().__init__()
|
||||
self.vipsImage = vipsImage
|
||||
@@ -91,7 +91,6 @@ def toVipsImage(vipsImageWrapper: VipsImage, options: scrypted_sdk.ImageOptions
|
||||
|
||||
async def createVipsMediaObject(image: VipsImage):
|
||||
ret = await scrypted_sdk.mediaManager.createMediaObject(image, scrypted_sdk.ScryptedMimeTypes.Image.value, {
|
||||
'timestamp': time.time() * 1000,
|
||||
'format': None,
|
||||
'width': image.width,
|
||||
'height': image.height,
|
||||
|
||||
Reference in New Issue
Block a user