mirror of
https://github.com/koush/scrypted.git
synced 2026-06-20 16:40:30 +01:00
python-codecs: fix potential leak/hang
This commit is contained in:
4
plugins/python-codecs/package-lock.json
generated
4
plugins/python-codecs/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/python-codecs",
|
||||
"version": "0.1.89",
|
||||
"version": "0.1.90",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/python-codecs",
|
||||
"version": "0.1.89",
|
||||
"version": "0.1.90",
|
||||
"devDependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/python-codecs",
|
||||
"version": "0.1.89",
|
||||
"version": "0.1.90",
|
||||
"description": "Python Codecs for Scrypted",
|
||||
"keywords": [
|
||||
"scrypted",
|
||||
|
||||
@@ -6,44 +6,56 @@ import pilimage
|
||||
from generator_common import createVideoFrame, createImageMediaObject
|
||||
import threading
|
||||
import asyncio
|
||||
import traceback
|
||||
|
||||
av = None
|
||||
try:
|
||||
import av
|
||||
av.logging.set_level(av.logging.PANIC)
|
||||
|
||||
av.logging.set_level(av.logging.PANIC)
|
||||
except:
|
||||
pass
|
||||
|
||||
async def generateVideoFramesLibav(mediaObject: scrypted_sdk.MediaObject, options: scrypted_sdk.VideoFrameGeneratorOptions = None, filter: Any = None) -> scrypted_sdk.VideoFrame:
|
||||
ffmpegInput: scrypted_sdk.FFmpegInput = await scrypted_sdk.mediaManager.convertMediaObjectToJSON(mediaObject, scrypted_sdk.ScryptedMimeTypes.FFmpegInput.value)
|
||||
videosrc = ffmpegInput.get('url')
|
||||
container = av.open(videosrc)
|
||||
# none of this stuff seems to work. might be libav being slow with rtsp.
|
||||
# container.no_buffer = True
|
||||
# container.gen_pts = False
|
||||
container.options['analyzeduration'] = '0'
|
||||
container.options['probesize'] = '500000'
|
||||
stream = container.streams.video[0]
|
||||
# stream.codec_context.thread_count = 1
|
||||
# stream.codec_context.low_delay = True
|
||||
# stream.codec_context.options['-analyzeduration'] = '0'
|
||||
# stream.codec_context.options['-probesize'] = '500000'
|
||||
|
||||
gray = options and options.get('format') == 'gray'
|
||||
async def generateVideoFramesLibav(
|
||||
mediaObject: scrypted_sdk.MediaObject,
|
||||
options: scrypted_sdk.VideoFrameGeneratorOptions = None,
|
||||
filter: Any = None,
|
||||
) -> scrypted_sdk.VideoFrame:
|
||||
ffmpegInput: scrypted_sdk.FFmpegInput = (
|
||||
await scrypted_sdk.mediaManager.convertMediaObjectToJSON(
|
||||
mediaObject, scrypted_sdk.ScryptedMimeTypes.FFmpegInput.value
|
||||
)
|
||||
)
|
||||
videosrc = ffmpegInput.get("url")
|
||||
|
||||
gray = options and options.get("format") == "gray"
|
||||
|
||||
sampleQueue = asyncio.Queue(1)
|
||||
loop = asyncio.get_event_loop()
|
||||
finished = False
|
||||
|
||||
def threadMain():
|
||||
try:
|
||||
container = av.open(videosrc)
|
||||
container.options["analyzeduration"] = "0"
|
||||
container.options["probesize"] = "500000"
|
||||
stream = container.streams.video[0]
|
||||
|
||||
for idx, frame in enumerate(container.decode(stream)):
|
||||
if finished:
|
||||
break
|
||||
|
||||
try:
|
||||
# non blocking put may fail if queue is not empty
|
||||
sampleQueue.put_nowait(frame)
|
||||
except:
|
||||
pass
|
||||
except:
|
||||
asyncio.run_coroutine_threadsafe(sampleQueue.put(None), loop = loop)
|
||||
traceback.print_exc()
|
||||
raise
|
||||
finally:
|
||||
asyncio.run_coroutine_threadsafe(sampleQueue.put(None), loop=loop)
|
||||
|
||||
thread = threading.Thread(target=threadMain)
|
||||
thread.start()
|
||||
@@ -61,17 +73,28 @@ async def generateVideoFramesLibav(mediaObject: scrypted_sdk.MediaObject, option
|
||||
break
|
||||
|
||||
if not firstFrame:
|
||||
print('first frame')
|
||||
print("first frame")
|
||||
print(time.time())
|
||||
firstFrame = True
|
||||
|
||||
if vipsimage.pyvips:
|
||||
if gray and frame.format.name.startswith('yuv') and frame.planes and len(frame.planes):
|
||||
vips = vipsimage.new_from_memory(memoryview(frame.planes[0]), frame.width, frame.height, 1)
|
||||
if (
|
||||
gray
|
||||
and frame.format.name.startswith("yuv")
|
||||
and frame.planes
|
||||
and len(frame.planes)
|
||||
):
|
||||
vips = vipsimage.new_from_memory(
|
||||
memoryview(frame.planes[0]), frame.width, frame.height, 1
|
||||
)
|
||||
elif gray:
|
||||
vips = vipsimage.pyvips.Image.new_from_array(frame.to_ndarray(format='gray'))
|
||||
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'))
|
||||
vips = vipsimage.pyvips.Image.new_from_array(
|
||||
frame.to_ndarray(format="rgb24")
|
||||
)
|
||||
|
||||
if not mo:
|
||||
vipsImage = vipsimage.VipsImage(vips)
|
||||
@@ -83,12 +106,19 @@ async def generateVideoFramesLibav(mediaObject: scrypted_sdk.MediaObject, option
|
||||
finally:
|
||||
await vipsImage.close()
|
||||
else:
|
||||
if gray and frame.format.name.startswith('yuv') and frame.planes and len(frame.planes):
|
||||
pil = pilimage.new_from_memory(memoryview(frame.planes[0]), frame.width, frame.height, 1)
|
||||
if (
|
||||
gray
|
||||
and frame.format.name.startswith("yuv")
|
||||
and frame.planes
|
||||
and len(frame.planes)
|
||||
):
|
||||
pil = pilimage.new_from_memory(
|
||||
memoryview(frame.planes[0]), frame.width, frame.height, 1
|
||||
)
|
||||
elif gray:
|
||||
rgb = frame.to_image()
|
||||
try:
|
||||
pil = rgb.convert('L')
|
||||
pil = rgb.convert("L")
|
||||
finally:
|
||||
rgb.close()
|
||||
else:
|
||||
@@ -104,4 +134,4 @@ async def generateVideoFramesLibav(mediaObject: scrypted_sdk.MediaObject, option
|
||||
finally:
|
||||
await pilImage.close()
|
||||
finally:
|
||||
container.close()
|
||||
finished = True
|
||||
|
||||
Reference in New Issue
Block a user