Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Idea]: Discarding default FFmpeg parameters and using FFmpeg Filters instead. #31

Closed
4 tasks done
abhiTronix opened this issue Aug 18, 2022 · 1 comment · Fixed by #32
Closed
4 tasks done

[Idea]: Discarding default FFmpeg parameters and using FFmpeg Filters instead. #31

abhiTronix opened this issue Aug 18, 2022 · 1 comment · Fixed by #32
Assignees
Labels
Bug 🐞 Something's wrong with Deffcode APIs. Idea 💡 New ideas for improving or enhancing DeFFcode APIs. Solved 🥅 Final goal achieved.
Milestone

Comments

@abhiTronix
Copy link
Owner

abhiTronix commented Aug 18, 2022

Issue guidelines

Issue Checklist

  • I have searched open or closed issues and found nothing related to my idea.
  • I have read the Documentation and it doesn't mention anything about my idea.
  • To my best knowledge, my idea wouldn't break something for other users.

Describe your Idea

This idea targets two problem that currently DeFFcode APIs fails to address:

  1. Discarding default FFmpeg parameters: Certain default FFmpeg parameters in DeFFcode API such as -framerate, -pix_fmt, -size cannot be removed/discarded from Decoding Pipeline in any way possible, and thereby present in every Pipeline that DeFFcode API has ever created. These parameters were thought to be extremely necessary for Pipeline to work but my recent tests shown that even if we remove these parameters the Decoding pipeline (with some changes) works totally fine. And instead, FFmpeg itself handles these parameter in best possible manner based on source and decoder provided by the user.

  2. Using FFmpeg Filters: Currently DeFFcode APIs fails to recognize values from filters like fps, format, scale which tends to break the pipeline with artifacts appearing on the output frames. This is due to fact that -framerate, -pix_fmt, -size like parameter are given advantage over filters values by the DeFFCode APIs and was primarily used by them to decode frames. For example if we scale=320:240 filter as follows, the output will be improper(with artifacts) since API tries to use FFmpeg parameter -s i.e. equal to source video frame size(for e.g. 1920x1080) which is way higher than require 320x240 as defined by the filter:

    # import the necessary packages
    from deffcode import FFdecoder
    import cv2
    
    # define params and custom filters
    ffparams = {
        "-vf": "scale=320:240",  # framerate=60fps
    }
    
    # initialize and formulate the decoder with params and custom filters
    decoder = FFdecoder(
        "t.mp4", frame_format="bgr24", verbose=True, **ffparams
    ).formulate()
    
    # grab the BGR24 frames from 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("Invalid 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()

Use Cases

Both Discarding default FFmpeg parameters and using FFmpeg Filters, are absolute necessity for decoding/transcoding video frames in GPU, as with FFmpeg commands like ffmpeg -y -vsync 0 -hwaccel_output_format cuda -hwaccel cuda -c:v h264_cuvid -i input.mp4 -vf "scale_npp=format=yuv420p,hwdownload,format=yuv420p,fps=25.0" -f rawvideo - fails to work with FFmpeg parameters -framerate, -pix_fmt, -size and throws Impossible to convert between the formats supported by the filter 'Parsed_null_0' and the filter 'auto_scale_0' Error reinitializing filters! Failed to inject frame into filter network: Function not implemented error. Therefore, implementing both these features will resolves issue with decoding/transcoding with DeFFcode APIs automatically (thus resolving #30).

Any other Relevant Information?

No response

@abhiTronix abhiTronix added Bug 🐞 Something's wrong with Deffcode APIs. WIP 🏗️ Work in Progress Idea 💡 New ideas for improving or enhancing DeFFcode APIs. labels Aug 18, 2022
@abhiTronix abhiTronix added this to the v0.2.4 milestone Aug 18, 2022
@abhiTronix abhiTronix self-assigned this Aug 18, 2022
abhiTronix added a commit that referenced this issue Aug 20, 2022
…ta (Fixes #31)

- ✨ Added three new metadata properties: `output_video_resolution`, `output_video_framerate`, `output_frames_pixfmt` for handling extracted Output Stream values, whenever additional FFmpeg parameters(such as FFmpeg filters) are defined.
- ⚗️ Added support for auto-handling additional FFmpeg parameters defined by `sourcer_params` dictionary parameters.
  - ⚡️ Implement new separate pipeline for parsing Output Stream metadata by decoding video source using `null` muxer for few microseconds whenever additional FFmpeg parameters(such as `-vf` filters) are defined by the user.
  - 🔧 Included new `metadata_output` internal parameter for holding Output Stream metadata splitted from original Sourcer Metadata extracted from new pipeline.
  - 🔧 Included new `output_video_resolution`, `output_video_framerate`, `output_frames_pixfmt` internal parameters for metadata properties, whenever Output Stream Metadata available.
  - 🚩 Added new `extract_output` boolean parameter to `extract_video_pixfmt` and `extract_resolution_framerate` internal methods for extracting output `pixel-format`, `framerate` and `resolution` using Output Stream metadata instead of Sourcer Metadata, whenever available.
- ⚡️ Added tuple to `sourcer_params` exception.
- ➕ Added `dict2Args` import.
- 💡 Updated code comments.
abhiTronix added a commit that referenced this issue Aug 20, 2022
…es. (Fixes #31)

- 🧱 Implemented new comprehensive support for both discarding key default FFmpeg parameters from Decoding pipeline simply by assigning them `null` string values, and concurrently using values extracted from Output Stream metadata properties (available only when FFmpeg filters are defined) for formulating Pipeline.
  - ✨ Added `null` string value support to `-framerate` and `-custom_resolution` attributes, as well as `frame_format` parameter for easily discarding them.
  - 🚧 Re-Implemented calculation of rawframe pixel-format.
    - 🏗️ Reconfigured default rawframe pixel-format, Now rawframe pixel-format will always default to `source_video_pixfmt` with `frame_format="null"`.
    - 💥 Now with `frame_format` parameter value either "null" or invalid or undefined, rawframe pixel-format value is taken from `output_frames_pixfmt` metadata property extracted from Output Stream (available only when filters are defined). If valid `output_video_resolution`  metadata property is found then it defaults to default pixel-format(calculated variably).
    - 🏗️ Also with `frame_format="null"`, `-pix_fmt` FFmpeg parameter will not be added to Decoding pipeline.
  - 🚧 Re-Implemented calculation of rawframe resolution value.
    - 💥 Now with `-custom_resolution` dictionary attribute value either "null" or invalid or undefined, rawframe resolution value is first taken from `output_video_resolution` metadata property extracted from Output Stream (available only when filters are defined), next from `source_video_resolution` metadata  property(extracted from Input Source Stream). If neither `output_video_resolution` nor `source_video_resolution` valid metadata properties are found then `RuntimeError` is raised.
    - 🏗️ Also with `-custom_resolution` dictionary attribute value "null", `-s/-size` FFmpeg parameter will not be added to Decoding pipeline.
  - 🚧 Re-Implemented calculation of output framerate value.
    - 💥 Now with `-framerate` dictionary attribute either null or invalid or undefined, output framerate value is first taken from `output_video_framerate` metadata property extracted from Output Stream (available only when filters are defined), next from `source_video_framerate` metadata  property(extracted from Input Source Stream). If neither `output_video_resolution` nor `source_video_framerate` valid metadata properties are found then `RuntimeError` is raised.
    - 🏗️ Also with `-framerate` dictionary attribute value "null", `-r/-framerate` FFmpeg parameter will not be added to Decoding pipeline.
- ⚡️ Implemented passing of simple/complex filters(via `-vf` and ffmpeg pre-headers(`-filter_complex`) and (via `-ffprefixes`) directly to Sourcer API's `sourcer_params` parameter for probing Output Stream metadata and filter values.
- ⚡️ Simplified raw frame dtype calculation based on selected pixel-format.
  - 💥 Now unsupported dtype pixel-format always defaults to `rgb24`.
  - 🏗️ Also, `output_frames_pixfmt` metadata property(if available) will be overridden to `rgb24`.
- 🏗️ Extended `YUV444p` reconstruction patch to all YUV based pixel-formats.
- ⚡️ Improved handling of `frame_format` parameter.
- 🔨 Renamed `source_metadata` internal parameter to `sourcer_metadata`.
- 🔥 Removed redundant dummy value for `output_frames_pixfmt` metadata property.
- 🔥 Removed redundant variable definitions.
- 🔊 Updated logging messages text and position.
- 💡 Updated code comments.
- ✏️ Fixed several typos.
abhiTronix added a commit that referenced this issue Aug 25, 2022
…r values. (Fixes #31)

- 🧱 Implemented new comprehensive support for both discarding key default FFmpeg parameters from Decoding pipeline simply by assigning them `null` string values, and concurrently using values extracted from Output Stream metadata properties _(available only when FFmpeg filters are defined)_ for formulating pipelines.
  - ✨ Added `null` string value support to `-framerate` and `-custom_resolution` attributes, as well as `frame_format` parameter for easily discarding them.
  - 🚧 Re-Implemented calculation of rawframe pixel-format.
    - 🏗️ Reconfigured default rawframe pixel-format, Now rawframe pixel-format will always default to `source_video_pixfmt` with `frame_format="null"`.
    - 💥 Now with `frame_format` parameter value either "null" or invalid or undefined, rawframe pixel-format value is taken from `output_frames_pixfmt` metadata property extracted from Output Stream (available only when filters are defined). If valid `output_video_resolution`  metadata property is found then it defaults to default pixel-format(calculated variably).
    - 🏗️ Also with `frame_format="null"`, `-pix_fmt` FFmpeg parameter will not be added to Decoding pipeline.
  - 🚧 Re-Implemented calculation of rawframe resolution value.
    - 💥 Now with `-custom_resolution` dictionary attribute value either "null" or invalid or undefined, rawframe resolution value is first taken from `output_video_resolution` metadata property extracted from Output Stream (available only when filters are defined), next from `source_video_resolution` metadata  property(extracted from Input Source Stream). If neither `output_video_resolution` nor `source_video_resolution` valid metadata properties are found then `RuntimeError` is raised.
    - 🏗️ Also with `-custom_resolution` dictionary attribute value "null", `-s/-size` FFmpeg parameter will not be added to Decoding pipeline.
  - 🚧 Re-Implemented calculation of output framerate value.
    - 💥 Now with `-framerate` dictionary attribute either null or invalid or undefined, output framerate value is first taken from `output_video_framerate` metadata property extracted from Output Stream (available only when filters are defined), next from `source_video_framerate` metadata  property(extracted from Input Source Stream). If neither `output_video_resolution` nor `source_video_framerate` valid metadata properties are found then `RuntimeError` is raised.
    - 🏗️ Also with `-framerate` dictionary attribute value "null", `-r/-framerate` FFmpeg parameter will not be added to Decoding pipeline.
- ⚡️ Implemented passing of simple `-vf` filters, complex `-filter_complex` filters, and pre-headers(via `-ffprefixes`) directly to Sourcer API's `sourcer_params` parameter for probing Output Stream metadata and filter values.
- ⚡️ Extended range of supported output frame pixel-formats. 
  - ✨ Added new pixel-formats to supported group by extending raw bits-per-component range.
- ⚡️ Simplified raw frame dtype calculation based on selected pixel-format.
  - 💥 Now unsupported dtype pixel-format always defaults to `rgb24`.
  - 🏗️ Also, `output_frames_pixfmt` metadata property(if available) will be overridden to `rgb24`.
- 🔥 Removed redundant dummy value for `output_frames_pixfmt` metadata property.
- 🚑️ Fixed critical KeyError bug arises due to missing output metadata properties.
  - ⚡️ Enforced `force_retrieve_missing` parameter in Sourcer API's `retrieve_metadata()` method for returning metadata missing in current Pipeline as `(metadata, metadata_missing)` tuple value instead of just `metadata`.
  - Added new `missing_prop` internal class variable for handling metadata properties missing,  received from Sourcer API.
  - 💥 Moved `ffdecoder_operational_mode` to missing metadata properties that cannot be updated but are read only.
  - 🚸 Added missing metadata properties to metadata class property object for easy printing along with other metadata information.
  - 🧑‍💻 Implemented missing metadata properties updation via. overridden metadata class property object.
    - ⚡️ Added `counterpart_prop` dict to handle all counterpart source properties for each missing output properties.
    - ⚡️ Implemented missing output properties auto-updation with counterpart source property is updated.
    - ♿️ Added separate case for handling only missing metadata properties and notifying user about counterpart source properties.
- 🐛 Fixed source metadata properties update bug causing non-existential missing metadata properties to be added to source metadata properties dictionary along with source metadata property.
    - 🚑️ Replaced `update()` calling  on `value` dict directly with explicitly assigning values to source metadata properties dictionary.
    - 🧑‍💻 Simplified `missing_prop` validation.
    - 🔥 Removed unwanted `continue` in middle of loop.
- 🔥 Remove unusable exclusive `yuv` frames patch.
- 🐛 Fixed `KeyError` bug arises due to wrong variable placement.
- 🩹 Fixed `approx_video_nframes` metadata property check.
- ⚡️ Improved handling of `frame_format` parameter.
- 🔊 Updated logging messages.
- 💡 Updated code comments.

- Sourcer API: 
  - 🧱 Added support for additional FFmpeg parameters and Output metadata
    - ✨ Added three new metadata properties: `output_video_resolution`, `output_video_framerate`, `output_frames_pixfmt` for handling extracted Output Stream values, whenever additional FFmpeg parameters(such as FFmpeg filters) are defined.
    - ⚗️ Added support for auto-handling additional FFmpeg parameters defined by `sourcer_params` dictionary parameters.
      - ⚡️ Implement new separate pipeline for parsing Output Stream metadata by decoding video source using `null` muxer for few microseconds whenever additional FFmpeg parameters(such as `-vf` filters) are defined by the user.
      - 🔧 Included new `metadata_output` internal parameter for holding Output Stream metadata splitted from original Sourcer Metadata extracted from new pipeline.
      - 🔧 Included new `output_video_resolution`, `output_video_framerate`, `output_frames_pixfmt` internal parameters for metadata properties, whenever Output Stream Metadata available.
      - 🚩 Added new `extract_output` boolean parameter to `extract_video_pixfmt` and `extract_resolution_framerate` internal methods for extracting output `pixel-format`, `framerate` and `resolution` using Output Stream metadata instead of Sourcer Metadata, whenever available.
    - ⚡️ Added tuple to `sourcer_params` exception.
    - ➕ Added `dict2Args` import.
  - ✨ Added new `force_retrieve_missing` parameter to `retrieve_metadata()` method for returning metadata missing in current Pipeline as `(metadata, metadata_missing)` tuple value instead of just `metadata`, when `force_retrieve_missing=True`.
  - ⚡️ Added various output stream metadata properties that are only available when additional FFmpeg parameters(such as filters) are defined manually, by assigning them counterpart source
    stream metadata property values
  - 🎨 Simplified JSON formatting and returning values logic.
  - 🔊 Updated logging messages text and position.
  - 🔥 Removed redundant variable definitions.
  - 💥 Renamed `output_video_resolution` metadata property to `output_frames_resolution`.
  - 💥 Renamed `output_video_framerate` metadata property to `output_framerate`.
  - 🚩 Changed related internal variable names w.r.t metadata property names.

- Docs:
  - 📝 Updated FFdecoder  API params docs w.r.t recent changes and supported for both discarded parameters and filter values.
    - 🚸 Added new admonitions to explain handling of "null" and (special-case), undefined, or invalid type values in various parameters/attributes.
    - ♿️ Added new footer reference explaining the handling of Default pixel-format for `frame_format` parameter.
    - 🩹 Added missing docs for `-default_stream_indexes` ffparams attribute.
  - 📝 Added docs for recently added additional FFmpeg parameter in Sourcer API's `sourcer_params` parameter.
    - 🔥 Removed unsupported `-custom_resolution` sourcer_params attributes from `sourcer_params` parameter docs.
    - 🔥 Removed redundant `-vcodec` and `-framerate` attributes from `sourcer_params` parameter docs.
  - 📝 Updated recipes docs to reflect recent changes in APIs. 
  - 📝 Updated parameter docs to reflect recent name changes.
  - 📝 Updated parameters/attributes introductory descriptions.
  - 💡 Updated code comments in examples.
  - 🩹 Fixed invalid hyperlink in ReadMe.md
  - ✏️ Fixed typos and context.

- CI: 
  - ✅ Added new unittests for discarded parameters and filter values. 
    - ✨ Added new `test_discard_n_filter_params` unittest for test recently added supported for both discarded parameters and filter values.
    - ☂️ Added various parametrize test data to attain maximum coverage.
    - ⚡️ Limited range of extracted frames, for finishing tests faster.
  - ✅ Updated unittests to reflect recent name changes.
  - 💡 Updated code comments.
  - ✏️ Fixed several typos.

- Utils:
   - ✏️ Fixed logger name typo.
@abhiTronix
Copy link
Owner Author

Successfully fixed and merged fix in commit 1918c8e

@abhiTronix abhiTronix added Solved 🥅 Final goal achieved. and removed WIP 🏗️ Work in Progress labels Aug 25, 2022
@abhiTronix abhiTronix pinned this issue Aug 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug 🐞 Something's wrong with Deffcode APIs. Idea 💡 New ideas for improving or enhancing DeFFcode APIs. Solved 🥅 Final goal achieved.
Projects
None yet
1 participant