abhiTronix/deffcode

[BUG] FFdecoder API throws IOError for streams without Video Bitrate and Framerate

Closed this issue · 0 comments

Brief Description

FFdecoder API currently unable to run and throws IOError for multimedia streams without Video Bitrate and Framerate defined, such as from lavfi input virtual device which has FFmpeg output:

Input #0, lavfi, from 'rgbtestsrc':
  Duration: N/A, start: 0.000000, bitrate: N/A
  Stream #0:0: Video: rawvideo (RGBA / 0x41424752), rgba, 320x240 [SAR 1:1 DAR 4:3], 25 tbr, 25 tbn

Acknowledgment

Current Environment

  • My DeFFcode version: v0.2.2-dev
  • My Python version: all
  • My Pip version: latest
  • My Operating System and its version: all

Expected Behavior

Should work for multimedia streams without Video Bitrate and Framerate defined

Actual Behavior

Throws IOError/OSError:

Traceback (most recent call last):
  File "p.py", line 10, in <module>
    decoder = FFdecoder("rgbtestsrc", source_demuxer="lavfi", frame_format="bgr24", verbose=True, **ffparams).formulate()
  File "C:\Users\foo\AppData\Roaming\Python\Python38\site-packages\deffcode\ffdecoder.py", line 162, in __init__
    Sourcer(
  File "C:\Users\foo\AppData\Roaming\Python\Python38\site-packages\deffcode\sourcer.py", line 224, in probe_stream
    raise IOError(
OSError: Invalid source provided. No usable Audio/Video stream detected. Aborting!!!

Possible Fix

Make Framerate extraction more robust by falling back to extracting TBR instead on failure because it is ffmpeg's best guess as to what the framerate actually is.

Steps to reproduce

Run this python code:

# import the necessary packages
from deffcode import FFdecoder
import cv2

# initialize and formulate the decoder with "rgbtestsrc" source of
# `1280x720` frame size and `30` framerate for BGR24 output
decoder = FFdecoder(
    "rgbtestsrc=size=1280x720:rate=30",
    source_demuxer="lavfi",
    frame_format="bgr24",
    verbose=True
).formulate()

# grab the BGR24 frame from the decoder
for frame in decoder.generateFrame():

    # check if frame is None
    if frame is None:
        break

    # {do something with the frame here}

    # Show output window
    cv2.imshow("Output", frame)

    # check for 'q' key if pressed
    key = cv2.waitKey(1) & 0xFF
    if key == ord("q"):
        break

# close output window
cv2.destroyAllWindows()

# terminate the decoder
decoder.terminate()