Skip to content

Commit

Permalink
python-codecs: implement hang protection
Browse files Browse the repository at this point in the history
  • Loading branch information
koush committed Jun 11, 2023
1 parent ea6e33d commit 8f83894
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 23 deletions.
8 changes: 4 additions & 4 deletions plugins/python-codecs/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@

{
// docker installation
"scrypted.debugHost": "koushik-ubuntu",
"scrypted.serverRoot": "/server",
// "scrypted.debugHost": "koushik-ubuntu",
// "scrypted.serverRoot": "/server",

// windows installation
// "scrypted.debugHost": "koushik-windows",
Expand All @@ -13,8 +13,8 @@
// "scrypted.serverRoot": "/home/pi/.scrypted",

// local checkout
// "scrypted.debugHost": "127.0.0.1",
// "scrypted.serverRoot": "/Users/koush/.scrypted",
"scrypted.debugHost": "127.0.0.1",
"scrypted.serverRoot": "/Users/koush/.scrypted",

"scrypted.pythonRemoteRoot": "${config:scrypted.serverRoot}/volume/plugin.zip",
"python.analysis.extraPaths": [
Expand Down
4 changes: 2 additions & 2 deletions plugins/python-codecs/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion plugins/python-codecs/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@scrypted/python-codecs",
"version": "0.1.73",
"version": "0.1.74",
"description": "Python Codecs for Scrypted",
"keywords": [
"scrypted",
Expand Down
1 change: 0 additions & 1 deletion plugins/python-codecs/src/gst_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ async def createPipelineIterator(pipeline: str, gst = None):
print(pipeline)
finished = concurrent.futures.Future()

newGst = not gst
if gst:
bin = Gst.parse_bin_from_description(pipeline, False)
gst.add(bin)
Expand Down
33 changes: 18 additions & 15 deletions plugins/python-codecs/src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,30 +149,33 @@ def multiprocess_exit():
os._exit(os.EX_OK)

class CodecFork:
async def generateVideoFramesGstreamer(self, mediaObject: scrypted_sdk.MediaObject, options: scrypted_sdk.VideoFrameGeneratorOptions, filter: Any, h264Decoder: str, postProcessPipeline: str) -> scrypted_sdk.VideoFrame:
async def generateVideoFrames(self, iter, src: str):
start = time.time()
try:
async for data in gstreamer.generateVideoFramesGstreamer(mediaObject, options, filter, h264Decoder, postProcessPipeline):
yield data
except Exception as e:
traceback.print_exc()
raise
finally:
print('gstreamer finished after %s' % (time.time() - start))
asyncio.get_event_loop().call_later(1, multiprocess_exit)
loop = asyncio.get_event_loop()
def timeoutExit():
print('Frame yield timed out, exiting pipeline.')
multiprocess_exit()

async def generateVideoFramesLibav(self, mediaObject: scrypted_sdk.MediaObject, options: scrypted_sdk.VideoFrameGeneratorOptions = None, filter: Any = None) -> scrypted_sdk.VideoFrame:
start = time.time()
try:
async for data in libav.generateVideoFramesLibav(mediaObject, options, filter):
while True:
data = await asyncio.wait_for(iter.__anext__(), timeout=10)
timeout = loop.call_later(10, timeoutExit)
yield data
except Exception as e:
timeout.cancel()
except Exception:
traceback.print_exc()
raise
finally:
print('libav finished after %s' % (time.time() - start))
print('%s finished after %s' % (src, time.time() - start))
asyncio.get_event_loop().call_later(1, multiprocess_exit)

async def generateVideoFramesGstreamer(self, mediaObject: scrypted_sdk.MediaObject, options: scrypted_sdk.VideoFrameGeneratorOptions, filter: Any, h264Decoder: str, postProcessPipeline: str) -> scrypted_sdk.VideoFrame:
async for data in self.generateVideoFrames(gstreamer.generateVideoFramesGstreamer(mediaObject, options, filter, h264Decoder, postProcessPipeline), "gstreamer"):
yield data

async def generateVideoFramesLibav(self, mediaObject: scrypted_sdk.MediaObject, options: scrypted_sdk.VideoFrameGeneratorOptions = None, filter: Any = None) -> scrypted_sdk.VideoFrame:
async for data in self.generateVideoFrames(libav.generateVideoFramesLibav(mediaObject, options, filter), "libav"):
yield data

async def fork():
return CodecFork()

0 comments on commit 8f83894

Please sign in to comment.