Skip to content

Commit

Permalink
python-codecs: fix libav and pil issues
Browse files Browse the repository at this point in the history
  • Loading branch information
koush committed Mar 27, 2023
1 parent 5472d90 commit 5961062
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 13 deletions.
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.20",
"version": "0.1.21",
"description": "Python Codecs for Scrypted",
"keywords": [
"scrypted",
Expand Down
20 changes: 18 additions & 2 deletions plugins/python-codecs/src/libav.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ async def generateVideoFramesLibav(mediaObject: scrypted_sdk.MediaObject, option
# stream.codec_context.options['-analyzeduration'] = '0'
# stream.codec_context.options['-probesize'] = '500000'

gray = options and options.get('format') == 'gray'

start = 0
try:
for idx, frame in enumerate(container.decode(stream)):
Expand All @@ -39,7 +41,12 @@ async def generateVideoFramesLibav(mediaObject: scrypted_sdk.MediaObject, option
continue
# print(frame)
if vipsimage.pyvips:
vips = vipsimage.pyvips.Image.new_from_array(frame.to_ndarray(format='rgb24'))
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'))
else:
vips = vipsimage.pyvips.Image.new_from_array(frame.to_ndarray(format='rgb24'))
vipsImage = vipsimage.VipsImage(vips)
try:
mo = await vipsimage.createVipsMediaObject(vipsImage)
Expand All @@ -48,7 +55,16 @@ async def generateVideoFramesLibav(mediaObject: scrypted_sdk.MediaObject, option
vipsImage.vipsImage = None
vips.invalidate()
else:
pil = frame.to_image()
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')
finally:
rgb.close()
else:
pil = frame.to_image()
pilImage = pilimage.PILImage(pil)
try:
mo = await pilimage.createPILMediaObject(pilImage)
Expand Down
23 changes: 15 additions & 8 deletions plugins/python-codecs/src/pilimage.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,26 @@ async def toBuffer(self, options: scrypted_sdk.ImageOptions = None) -> bytearray

if not options or not options.get('format', None):
def format():
bytesArray = io.BytesIO()
pilImage.pilImage.save(bytesArray, format='JPEG')
return bytesArray.getvalue()
return pilImage.pilImage.tobytes()
return await to_thread(format)
elif options['format'] == 'rgb':
def format():
rgb = pilImage.pilImage
if rgb.format == 'RGBA':
rgb = rgb.convert('RGB')
return rgb.tobytes()
rgbx = pilImage.pilImage
if rgbx.format != 'RGBA':
return rgbx.tobytes()
rgb = rgbx.convert('RGB')
try:
return rgb.tobytes()
finally:
rgb.close()
return await to_thread(format)

return await to_thread(lambda: pilImage.pilImage.write_to_buffer('.' + options['format']))
def save():
bytesArray = io.BytesIO()
pilImage.pilImage.save(bytesArray, format=options['format'])
return bytesArray.getvalue()

return await to_thread(lambda: save())

async def toPILImage(self, options: scrypted_sdk.ImageOptions = None):
return await to_thread(lambda: toPILImage(self, options))
Expand Down

0 comments on commit 5961062

Please sign in to comment.