Repository: abhiTronix/deffcode (language: python)

Issue:
[Idea]: Discarding default FFmpeg parameters and using FFmpeg Filters instead.
### Issue guidelines

- [X] I've read the [Issue Guidelines](https://abhitronix.github.io/deffcode/latest/contribution/issue/#submitting-an-issue-guidelines) and wholeheartedly agree.

### Issue Checklist

- [X] I have searched open or closed [issues](https://github.com/abhiTronix/deffcode/issues) and found nothing related to my idea.
- [X] I have read the [Documentation](https://abhitronix.github.io/deffcode/latest) and it doesn't mention anything about my idea.
- [X] 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:

    ```python
    # 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_
[Idea]: Similar to OpenCV, Index based Camera Device Capture
### Issue guidelines

- [X] I've read the [Issue Guidelines](https://abhitronix.github.io/deffcode/latest/contribution/issue/#submitting-an-issue-guidelines) and wholeheartedly agree.

### Issue Checklist

- [X] I have searched open or closed [issues](https://github.com/abhiTronix/deffcode/issues) and found nothing related to my idea.
- [X] I have read the [Documentation](https://abhitronix.github.io/deffcode/latest) and it doesn't mention anything about my idea.
- [X] To my best knowledge, my idea wouldn't break something for other users.

### Describe your Idea

Currently, DeFFcode users have to manually assign device name or its path using [`source`](https://abhitronix.github.io/deffcode/latest/recipes/reference/sourcer/params/#source) parameter and the demuxer using [`source_demuxer`](https://abhitronix.github.io/deffcode/latest/recipes/reference/sourcer/params/#source_demuxer) parameter of the respective API for the given input device. And thereby makes this feature less user-friendly, and complicated for everyday user who might find it extremely difficult to replicate. 

This issue will track the **Index based Camera Device Capture feature**, which implements Device Indexing _(similar to OpenCV)_,  where the user just have to assign device index as integer _(-n to n-1<sup>th</sup>)_ in `source` parameter of DeFFcode APIs to directly access the  given input device, thus making things much simpler. 

### Use Cases

The **Index based Camera Device Capture feature** implements Device Indexing _(similar to OpenCV)_,  where the user just have to assign device index as integer _(-n to n-1<sup>th</sup>)_ in `source` parameter of DeFFcode APIs to directly access the  given input device in few seconds. 

This feature is much better than manually Identifying and Specifying Video Capture Device Name/Path and suitable Demuxer on different OS platforms, thus minimizing perceived complexity of decoding Live Feed Devices.

### Any other Relevant Information?

_No response_


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml
index d118185..0290f13 100644
--- a/.github/workflows/CIlinux.yml
+++ b/.github/workflows/CIlinux.yml
@@ -65,7 +65,7 @@ jobs:
         shell: bash
       - name: Run pytest and flake8
         run: |
-          timeout 1200 sudo python -m pytest --verbose --cov=deffcode --cov-report=xml  --cov-report term-missing tests/ || code=$?; if [[ $code -ne 124 && $code -ne 0 ]]; then exit $code; else echo "EXIT_CODE=$code" >>$GITHUB_ENV; fi
+          timeout 1200 sudo python -m pytest -sv --cov=deffcode --cov-report=xml --cov-report term-missing tests/ || code=$?; if [[ $code -ne 124 && $code -ne 0 ]]; then exit $code; else echo "EXIT_CODE=$code" >>$GITHUB_ENV; fi
           flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
         if: success()
       - name: Upload coverage to Codecov
diff --git a/README.md b/README.md
index bdd3992..81211b9 100644
--- a/README.md
+++ b/README.md
@@ -50,11 +50,11 @@ DeFFcode - A cross-platform **High-performance Video Frames Decoder** that flexi
 
 &thinsp;
 
-**<ins>Highly Adaptive</ins> -** _DeFFcode APIs implements a **standalone highly-extensible wrapper around [FFmpeg][ffmpeg]** multimedia framework. These APIs **supports a wide-ranging media streams as input** source such as [live USB/Virtual/IP camera feeds][capturing-and-previewing-frames-from-a-webcam], [regular multimedia files][capturing-rgb-frames-from-a-video-file], [screen recordings][capturing-and-previewing-frames-from-your-desktop], [image sequences][decoding-image-sequences], [network URL schemes][decoding-network-streams] (such as HTTP(s), RTP/RSTP, etc.), so on and so forth._
+**<ins>Highly Adaptive</ins> -** _DeFFcode APIs implements a **standalone highly-extensible wrapper around [FFmpeg][ffmpeg]** multimedia framework. These APIs **supports a wide-ranging media streams as input** source such as [live USB/Virtual/IP camera feeds][capturing-and-previewing-frames-from-a-webcam], [regular multimedia files][decoding-video-files], [screen recordings][capturing-and-previewing-frames-from-your-desktop], [image sequences][decoding-image-sequences], [network URL schemes][decoding-network-streams] (such as HTTP(s), RTP/RSTP, etc.), so on and so forth._
 
 **<ins>Highly Flexible</ins> -** _DeFFcode APIs gains an edge over other FFmpeg Wrappers by providing **complete control over the underline pipeline** including **access to almost any FFmpeg specification thinkable** such as specifying framerate, resolution, hardware decoder(s), filtergraph(s), and pixel-format(s) that are readily **supported by all well known Computer Vision libraries**._
 
-**<ins>Highly Convenient</ins> -** _FFmpeg has a steep learning curve especially for users unfamiliar with a command line interface. DeFFcode helps users by maintaining the **same standard [OpenCV-Python](https://docs.opencv.org/4.x/d6/d00/tutorial_py_root.html) (Python API for OpenCV) coding syntax for its APIs**, thereby making it even **easier to learn, create, and develop FFmpeg based apps** in Python._
+**<ins>Highly Convenient</ins> -** _FFmpeg has a steep learning curve especially for users unfamiliar with a command line interface. DeFFcode helps users by providing similar to OpenCV, [**Index based Camera Device Capturing**][decoding-camera-devices-using-indexes] and the **same standard [OpenCV-Python](https://docs.opencv.org/4.x/d6/d00/tutorial_py_root.html) (Python API for OpenCV) coding syntax for its APIs**, thereby making it even **easier to learn, create, and develop FFmpeg based apps** in Python._
 
 &nbsp;
 
@@ -66,6 +66,7 @@ Here are some key features that stand out:
 - Flexible API with access to almost any FFmpeg specification thinkable.
 - Supports a wide-range of media streams/devices/protocols as input source.
 - Curated list of well-documented recipes ranging from [**Basic**][basic-recipes] to [**Advanced**][advanced-recipes] skill levels.
+- Hands down the easiest [**Index based Camera Device Capturing**][decoding-camera-devices-using-indexes], similar to OpenCV.
 - Easy to code **Real-time [Simple][transcoding-live-simple-filtergraphs] & [Complex][transcoding-live-complex-filtergraphs] Filtergraphs**. _(Yes, You read it correctly "Real-time"!)_
 - Lightning fast dedicated **GPU-Accelerated Video [Decoding][hardware-accelerated-video-decoding] & [Transcoding][hardware-accelerated-video-transcoding]**.
 - Enables precise FFmpeg [**Key-frame Seeking**][extracting-key-frames-as-png-image] with pinpoint accuracy.
@@ -121,8 +122,8 @@ Once you have DeFFcode installed, checkout our Well-Documented **[Recipes 🍱][
 - [Accessing RGB frames from a video file][accessing-rgb-frames-from-a-video-file]
 - [Capturing and Previewing BGR frames from a video file][capturing-and-previewing-bgr-frames-from-a-video-file] _(OpenCV Support)_
 - [Playing with any other FFmpeg pixel formats][capturing-and-previewing-bgr-frames-from-a-video-file]
-- [Capturing and Previewing frames from a Webcam][capturing-and-previewing-frames-from-a-webcam]
-- [Capturing and Previewing frames from your Desktop][capturing-and-previewing-frames-from-your-desktop] _(Screen Recording)_
+- [Enumerating all Camera Devices with Indexes][enumerating-all-camera-devices-with-indexes]
+- [Capturing and Previewing frames from a Camera using Indexes][capturing-and-previewing-frames-from-a-camera-using-indexes]
 - [Capturing and Previewing frames from a HTTPs Stream][capturing-and-previewing-frames-from-a-https-stream]
 - [Capturing and Previewing frames from a RTSP/RTP Stream][capturing-and-previewing-frames-from-a-rtsprtp-stream]
 - [Capturing and Previewing frames from Sequence of images][capturing-and-previewing-frames-from-sequence-of-images]
@@ -174,6 +175,8 @@ Once you have DeFFcode installed, checkout our Well-Documented **[Recipes 🍱][
 - [Generate and Decode frames from Gradients with custom Text effect][generate-and-decode-frames-from-gradients-with-custom-text-effect]
 - [Generate and Decode frames from Mandelbrot test pattern with vectorscope & waveforms][generate-and-decode-frames-from-mandelbrot-test-pattern-with-vectorscope-waveforms]
 - [Generate and Decode frames from Game of Life Visualization][generate-and-decode-frames-from-game-of-life-visualization]
+- [Capturing and Previewing frames from a Webcam using Custom Demuxer][capturing-and-previewing-frames-from-a-webcam-using-custom-demuxer]
+- [Capturing and Previewing frames from your Desktop][capturing-and-previewing-frames-from-your-desktop] _(Screen Recording)_
 - [GPU-accelerated Hardware-based Video Decoding][gpu-accelerated-hardware-based-video-decoding]
 
 </details>
@@ -312,18 +315,18 @@ It is something I am doing with my own free time. But so much more needs to be d
 
 Here is a Bibtex entry you can use to cite this project in a publication:
 
-[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6976948.svg)](https://doi.org/10.5281/zenodo.6976948)
+[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6984364.svg)](https://doi.org/10.5281/zenodo.6984364)
 
 ```BibTeX
 @software{deffcode,
   author       = {Abhishek Thakur},
-  title        = {abhiTronix/deffcode: v0.2.2},
+  title        = {abhiTronix/deffcode: v0.2.3},
   month        = aug,
   year         = 2022,
   publisher    = {Zenodo},
-  version      = {v0.2.2},
-  doi          = {10.5281/zenodo.6976948},
-  url          = {https://doi.org/10.5281/zenodo.6976948}
+  version      = {v0.2.3},
+  doi          = {10.5281/zenodo.6984364},
+  url          = {https://doi.org/10.5281/zenodo.6984364}
 }
 ```
 
@@ -359,7 +362,7 @@ Internal URLs
 [release]:https://github.com/abhiTronix/deffcode/releases/latest
 [recipes]:https://abhitronix.github.io/deffcode/latest/recipes/basic/
 [license]:https://github.com/abhiTronix/deffcode/blob/master/LICENSE
-[help]:https://abhitronix.github.io/deffcode/latest/https://abhitronix.github.io/deffcode/latest/help/get_help
+[help]:https://abhitronix.github.io/deffcode/latest/help/get_help
 [installation-notes]:https://abhitronix.github.io/deffcode/latest/installation/#installation-notes
 [ffdecoder-api]:https://abhitronix.github.io/deffcode/latest/reference/ffdecoder/#ffdecoder-api
 [sourcer-api]:https://abhitronix.github.io/deffcode/latest/reference/sourcer/#sourcer-api
@@ -370,7 +373,7 @@ Basic Recipes
 -->
 [basic-recipes]:https://abhitronix.github.io/deffcode/latest/recipes/basic/
 [decoding-video-files]:https://abhitronix.github.io/deffcode/latest/recipes/basic/decode-video-files/#decoding-video-files
-[decoding-live-feed-devices]:https://abhitronix.github.io/deffcode/latest/recipes/basic/decode-live-feed-devices/#decoding-live-feed-devices
+[decoding-camera-devices-using-indexes]:https://abhitronix.github.io/deffcode/latest/recipes/basic/decode-camera-devices/#decoding-camera-devices-using-indexes
 [decoding-network-streams]:https://abhitronix.github.io/deffcode/latest/recipes/basic/decode-network-streams/#decoding-network-streams
 [decoding-image-sequences]:https://abhitronix.github.io/deffcode/latest/recipes/basic/decode-image-sequences/#decoding-image-sequences
 [transcode-live-frames]:https://abhitronix.github.io/deffcode/latest/recipes/basic/transcode-live-frames/
@@ -381,8 +384,8 @@ Basic Recipes
 [accessing-rgb-frames-from-a-video-file]:https://abhitronix.github.io/deffcode/latest/recipes/basic/decode-video-files/#accessing-rgb-frames-from-a-video-file
 [capturing-and-previewing-bgr-frames-from-a-video-file]:https://abhitronix.github.io/deffcode/latest/recipes/basic/decode-video-files/#capturing-and-previewing-bgr-frames-from-a-video-file
 [capturing-and-previewing-bgr-frames-from-a-video-file]:https://abhitronix.github.io/deffcode/latest/recipes/basic/decode-video-files/#capturing-and-previewing-bgr-frames-from-a-video-file
-[capturing-and-previewing-frames-from-a-webcam]:https://abhitronix.github.io/deffcode/latest/recipes/basic/decode-live-feed-devices/#capturing-and-previewing-frames-from-a-webcam
-[capturing-and-previewing-frames-from-your-desktop]:https://abhitronix.github.io/deffcode/latest/recipes/basic/decode-live-feed-devices/#capturing-and-previewing-frames-from-your-desktop
+[enumerating-all-camera-devices-with-indexes]:https://abhitronix.github.io/deffcode/latest/recipes/basic/decode-camera-devices/#enumerating-all-camera-devices-with-indexes
+[capturing-and-previewing-frames-from-a-camera-using-indexes]:https://abhitronix.github.io/deffcode/latest/recipes/basic/decode-camera-devices/#capturing-and-previewing-frames-from-a-camera-using-indexes
 [capturing-and-previewing-frames-from-a-https-stream]:https://abhitronix.github.io/deffcode/latest/recipes/basic/decode-network-streams/#capturing-and-previewing-frames-from-a-https-stream
 [capturing-and-previewing-frames-from-a-rtsprtp-stream]:https://abhitronix.github.io/deffcode/latest/recipes/basic/decode-network-streams/#capturing-and-previewing-frames-from-a-rtsprtp-stream
 [capturing-and-previewing-frames-from-sequence-of-images]:https://abhitronix.github.io/deffcode/latest/recipes/basic/decode-image-sequences/#capturing-and-previewing-frames-from-sequence-of-images
@@ -404,6 +407,7 @@ Advanced Recipes
 -->
 [advanced-recipes]:https://abhitronix.github.io/deffcode/latest/recipes/advanced/
 [decoding-live-virtual-sources]:https://abhitronix.github.io/deffcode/latest/recipes/advanced/decode-live-virtual-sources/#decoding-live-virtual-sources
+[decoding-live-feed-devices]:https://abhitronix.github.io/deffcode/latest/recipes/advanced/decode-live-feed-devices/#decoding-live-feed-devices
 [hardware-accelerated-video-decoding]:https://abhitronix.github.io/deffcode/latest/recipes/advanced/decode-hw-acceleration/#hardware-accelerated-video-decoding
 [transcoding-live-complex-filtergraphs]:https://abhitronix.github.io/deffcode/latest/recipes/advanced/transcode-live-frames-complexgraphs/#transcoding-live-complex-filtergraphs
 [transcoding-video-art-with-filtergraphs]:https://abhitronix.github.io/deffcode/latest/recipes/advanced/transcode-art-filtergraphs/#transcoding-video-art-with-filtergraphs
@@ -423,6 +427,8 @@ Advanced Recipes
 [transcoding-video-art-with-yuv-bitplane-visualization]:https://abhitronix.github.io/deffcode/latest/recipes/advanced/transcode-art-filtergraphs/#transcoding-video-art-with-yuv-bitplane-visualization
 [transcoding-video-art-with-ghosting-effect]:https://abhitronix.github.io/deffcode/latest/recipes/advanced/transcode-art-filtergraphs/#transcoding-video-art-with-ghosting-effect
 [transcoding-video-art-with-pixelation-effect]:https://abhitronix.github.io/deffcode/latest/recipes/advanced/transcode-art-filtergraphs/#transcoding-video-art-with-pixelation-effect
+[capturing-and-previewing-frames-from-a-webcam-using-custom-demuxer]:https://abhitronix.github.io/deffcode/latest/recipes/advanced/decode-live-feed-devices/#capturing-and-previewing-frames-from-a-webcam-using-custom-demuxer
+[capturing-and-previewing-frames-from-your-desktop]:https://abhitronix.github.io/deffcode/latest/recipes/advanced/decode-live-feed-devices/#capturing-and-previewing-frames-from-your-desktop
 [gpu-accelerated-hardware-based-video-transcoding-with-writegear-api]:https://abhitronix.github.io/deffcode/latest/recipes/advanced/transcode-hw-acceleration/#gpu-accelerated-hardware-based-video-transcoding-with-writegear-api
 [added-new-attributes-to-metadata-in-ffdecoder-api]:https://abhitronix.github.io/deffcode/latest/recipes/advanced/update-metadata/#added-new-attributes-to-metadata-in-ffdecoder-api
 [overriding-source-video-metadata-in-ffdecoder-api]:https://abhitronix.github.io/deffcode/latest/recipes/advanced/update-metadata/#overriding-source-video-metadata-in-ffdecoder-api
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 6ea637f..876232c 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -69,7 +69,7 @@ steps:
   displayName: 'Install pip dependencies'
 
 - script: |
-    timeout 1500 pytest --verbose --cov=deffcode --cov-report=xml --cov-report=html --cov-report term-missing tests/ || code=$?; if [[ $code -ne 124 && $code -ne 0 ]]; then exit $code; else echo "##vso[task.setvariable variable=exit_code]$code"; fi
+    timeout 1500 pytest -sv --cov=deffcode --cov-report=xml --cov-report=html --cov-report term-missing tests/ || code=$?; if [[ $code -ne 124 && $code -ne 0 ]]; then exit $code; else echo "##vso[task.setvariable variable=exit_code]$code"; fi
   displayName: 'pytest'
   
 - bash: |
diff --git a/deffcode/ffdecoder.py b/deffcode/ffdecoder.py
index bcd190d..2d259ef 100644
--- a/deffcode/ffdecoder.py
+++ b/deffcode/ffdecoder.py
@@ -100,7 +100,7 @@ def __init__(
 
         # define frame pixel-format for decoded frames
         self.__frame_format = (
-            frame_format.strip() if isinstance(frame_format, str) else None
+            frame_format.lower().strip() if isinstance(frame_format, str) else None
         )
 
         # handles user-defined parameters
@@ -143,6 +143,22 @@ def __init__(
         # reset improper values
         sourcer_params = {} if not isinstance(sourcer_params, dict) else sourcer_params
 
+        # handle user ffmpeg pre-headers(parameters such as `-re`) parameters (must be a list)
+        self.__ffmpeg_prefixes = self.__extra_params.pop("-ffprefixes", [])
+        # check if not valid type
+        if not isinstance(self.__ffmpeg_prefixes, list):
+            # log it
+            logger.warning(
+                "Discarding invalid `-ffprefixes` value of wrong type: `{}`!".format(
+                    type(self.__ffmpeg_prefixes).__name__
+                )
+            )
+            # reset improper values
+            self.__ffmpeg_prefixes = []
+        else:
+            # also pass valid ffmpeg pre-headers to Sourcer API
+            sourcer_params["-ffprefixes"] = self.__ffmpeg_prefixes
+
         # pass parameter(if specified) to Sourcer API, specifying where to save the downloaded FFmpeg Static
         # assets on Windows(if specified)
         sourcer_params["-ffmpeg_download_path"] = self.__extra_params.pop(
@@ -160,10 +176,15 @@ def __init__(
             else default_stream_indexes
         )
 
+        # pass FFmpeg filter to Sourcer API params for processing
+        if set(["-vf", "-filter_complex"]).intersection(self.__extra_params.keys()):
+            key = "-vf" if "-vf" in self.__extra_params else "-filter_complex"
+            sourcer_params[key] = self.__extra_params[key]
+
         # define dict to store user-defined parameters
         self.__user_metadata = {}
         # extract and assign source metadata as dict
-        self.__source_metadata = (
+        (self.__sourcer_metadata, self.__missing_prop) = (
             Sourcer(
                 source=source,
                 source_demuxer=source_demuxer,
@@ -172,13 +193,11 @@ def __init__(
                 **sourcer_params
             )
             .probe_stream(default_stream_indexes=default_stream_indexes)
-            .retrieve_metadata()
+            .retrieve_metadata(force_retrieve_missing=True)
         )
-        # add dummy value for `output_frames_pixfmt` source metadata
-        self.__source_metadata["output_frames_pixfmt"] = "unknown"
 
         # handle valid FFmpeg assets location
-        self.__ffmpeg = self.__source_metadata["ffmpeg_binary_path"]
+        self.__ffmpeg = self.__sourcer_metadata["ffmpeg_binary_path"]
 
         # handle pass-through audio mode works in conjunction with WriteGear [TODO]
         self.__passthrough_mode = self.__extra_params.pop("-passthrough_audio", False)
@@ -186,20 +205,20 @@ def __init__(
             self.__passthrough_mode = False
 
         # handle mode of operation
-        if self.__source_metadata["source_has_image_sequence"]:
+        if self.__sourcer_metadata["source_has_image_sequence"]:
             # image-sequence mode
             self.__opmode = "imgseq"
         elif (
-            self.__source_metadata[
+            self.__sourcer_metadata[
                 "source_has_video"
             ]  # audio is only for pass-through, not really for audio decoding yet.
-            and self.__source_metadata["source_has_audio"]
+            and self.__sourcer_metadata["source_has_audio"]
             and self.__passthrough_mode  # [TODO]
         ):
             self.__opmode = "av"
-        # elif __defop_mode == "ao" and self.__source_metadata.contains_audio: # [TODO]
+        # elif __defop_mode == "ao" and self.__sourcer_metadata.contains_audio: # [TODO]
         #    self.__opmode = "ao"
-        elif self.__source_metadata["source_has_video"]:
+        elif self.__sourcer_metadata["source_has_video"]:
             # video-only mode
             self.__opmode = "vo"
         else:
@@ -208,23 +227,23 @@ def __init__(
                 "Unable to find any usable video stream in the given source!"
             )
         # store as metadata
-        self.__source_metadata["ffdecoder_operational_mode"] = self.__supported_opmodes[
+        self.__missing_prop["ffdecoder_operational_mode"] = self.__supported_opmodes[
             self.__opmode
         ]
-        # and log it
-        self.__verbose_logs and logger.critical(
-            "Activating {} Mode of Operation.".format(
-                self.__supported_opmodes[self.__opmode]
-            )
-        )
 
-        # handle user-defined framerate
-        __framerate = self.__extra_params.pop("-framerate", 0.0)
-        if not (__framerate is None) and isinstance(__framerate, (float, int)):
+        # handle user-defined output framerate
+        __framerate = self.__extra_params.pop("-framerate", None)
+        if (
+            isinstance(__framerate, str)
+            and __framerate
+            == "null"  # special mode to discard `-framerate/-r` parameter
+        ):
+            self.__inputframerate = __framerate
+        elif isinstance(__framerate, (float, int)):
             self.__inputframerate = float(__framerate) if __framerate > 0.0 else 0.0
         else:
             # warn if wrong type
-            logger.warning(
+            not (__framerate is None) and logger.warning(
                 "Discarding invalid `-framerate` value of wrong type `{}`!".format(
                     type(__framerate).__name__
                 )
@@ -232,19 +251,26 @@ def __init__(
             # reset to default
             self.__inputframerate = 0.0
 
-        # FFmpeg parameter `-s` is unsupported
-        if not (self.__extra_params.pop("-s", None) is None):
-            logger.warning(
-                "Discarding user-defined `-s` FFmpeg parameter as it can only be assigned with `-custom_resolution` attribute! Read docs for more details."
-            )
-        # handle user defined decoded frame resolution(must be a tuple or list)
+        # handle user defined decoded frame resolution
         self.__custom_resolution = self.__extra_params.pop("-custom_resolution", None)
-        if not (self.__custom_resolution is None) and (
-            not isinstance(self.__custom_resolution, (list, tuple))
-            or len(self.__custom_resolution) != 2
+        if (
+            isinstance(self.__custom_resolution, str)
+            and self.__custom_resolution
+            == "null"  # special mode to discard `-size/-s` parameter
+        ) or (
+            isinstance(self.__custom_resolution, (list, tuple))
+            and len(self.__custom_resolution)
+            == 2  # valid resolution(must be a tuple or list)
         ):
             # log it
-            logger.warning(
+            self.__verbose_logs and not isinstance(
+                self.__custom_resolution, str
+            ) and logger.debug(
+                "Setting raw frames size: `{}`.".format(self.__custom_resolution)
+            )
+        else:
+            # log it
+            not (self.__custom_resolution is None) and logger.warning(
                 "Discarding invalid `-custom_resolution` value: `{}`!".format(
                     self.__custom_resolution
                 )
@@ -252,18 +278,6 @@ def __init__(
             # reset improper values
             self.__custom_resolution = None
 
-        # handle user defined ffmpeg pre-headers(parameters such as `-re`) parameters (must be a list)
-        self.__ffmpeg_prefixes = self.__extra_params.pop("-ffprefixes", [])
-        if not isinstance(self.__ffmpeg_prefixes, list):
-            # log it
-            logger.warning(
-                "Discarding invalid `-ffprefixes` value of wrong type: `{}`!".format(
-                    type(self.__ffmpeg_prefixes).__name__
-                )
-            )
-            # reset improper values
-            self.__ffmpeg_prefixes = []
-
     def formulate(self):
 
         """
@@ -280,8 +294,9 @@ def formulate(self):
             # dynamically pre-assign a default video-decoder (if not assigned by user).
             supported_vdecodecs = get_supported_vdecoders(self.__ffmpeg)
             default_vdecodec = (
-                self.__source_metadata["source_video_decoder"]
-                if self.__source_metadata["source_video_decoder"] in supported_vdecodecs
+                self.__sourcer_metadata["source_video_decoder"]
+                if self.__sourcer_metadata["source_video_decoder"]
+                in supported_vdecodecs
                 else "unknown"
             )
             if "-c:v" in self.__extra_params:
@@ -336,113 +351,235 @@ def formulate(self):
                     output_params["-frames:v"] = value
 
             # dynamically calculate default raw-frames pixel format(if not assigned by user).
+            # notify FFmpeg `-pix_fmt` parameter cannot be assigned directly
+            if "-pix_fmt" in self.__extra_params:
+                logger.warning(
+                    "Discarding user-defined `-pix_fmt` value as it can only be assigned with `frame_format` parameter!"
+                )
+                self.__extra_params.pop("-pix_fmt", None)
+            # get supported FFmpeg pixfmt data with depth and bpp(bits-per-pixel)
             self.__ff_pixfmt_metadata = get_supported_pixfmts(self.__ffmpeg)
             supported_pixfmts = [fmts[0] for fmts in self.__ff_pixfmt_metadata]
+
+            # calculate default pixel-format
+            # Check special case  - `frame_format`(or `-pix_fmt`) parameter discarded from pipeline
+            self.__frame_format == "null" and logger.critical(
+                "Manually discarding `frame_format`(or `-pix_fmt`) parameter from this pipeline."
+            )
+            # choose between rgb24(if available) or source pixel-format
+            # otherwise, only source pixel-format for special case
             default_pixfmt = (
                 "rgb24"
-                if "rgb24" in supported_pixfmts
-                else self.__source_metadata["source_video_pixfmt"]
+                if "rgb24" in supported_pixfmts and self.__frame_format != "null"
+                else self.__sourcer_metadata["source_video_pixfmt"]
             )
-            # assigning `-pix_fmt` parameter cannot be assigned directly
-            if "-pix_fmt" in self.__extra_params:
-                logger.warning(
-                    "Discarding user-defined `-pix_fmt` value as it can only be assigned with `frame_format` parameter! Read docs for more details."
-                )
-                self.__extra_params.pop("-pix_fmt", None)
             # assign output raw-frames pixel format
+            rawframe_pixfmt = None
             if (
-                "output_frames_pixfmt" in self.__source_metadata
-                and self.__source_metadata["output_frames_pixfmt"] in supported_pixfmts
-            ):
-                # check if manually defined via `metadata` property object
-                # assign if valid and supported
-                output_params["-pix_fmt"] = self.__source_metadata[
-                    "output_frames_pixfmt"
-                ].strip()
-            elif (
                 not (self.__frame_format is None)
                 and self.__frame_format in supported_pixfmts
             ):
-                # check if assigned via `frame_format` parameter
+                # check if valid and supported `frame_format` parameter assigned
+                rawframe_pixfmt = self.__frame_format.strip()
+                self.__verbose_logs and logger.info(
+                    "User-defined `{}` frame pixel-format will be used for this pipeline.".format(
+                        rawframe_pixfmt
+                    )
+                )
+            elif (
+                "output_frames_pixfmt"
+                in self.__sourcer_metadata  # means `format` filter is defined
+                and self.__sourcer_metadata["output_frames_pixfmt"] in supported_pixfmts
+            ):
                 # assign if valid and supported
-                output_params["-pix_fmt"] = self.__frame_format.strip()
+                rawframe_pixfmt = self.__sourcer_metadata[
+                    "output_frames_pixfmt"
+                ].strip()
+                self.__verbose_logs and logger.info(
+                    "FFmpeg filter values will be used for this pipeline for defining output pixel-format."
+                )
             else:
                 # reset to default if not supported
-                not (self.__frame_format is None) and logger.critical(
-                    "Provided FFmpeg does not support `{}` pixel format(pix_fmt). Switching to default `{}`!".format(
-                        self.__frame_format, "rgb24"
+                rawframe_pixfmt = default_pixfmt
+                # log it accordingly
+                if self.__frame_format is None:
+                    logger.info(
+                        "Using default `{}` pixel-format for this pipeline.".format(
+                            default_pixfmt
+                        )
+                    )
+                else:
+                    logger.warning(
+                        "{} Switching to default `{}` pixel-format!".format(
+                            "Provided FFmpeg does not supports `{}` pixel-format.".format(
+                                self.__sourcer_metadata["output_frames_pixfmt"]
+                                if "output_frames_pixfmt" in self.__sourcer_metadata
+                                else self.__frame_format
+                            )
+                            if self.__frame_format != "null"
+                            else "No usable pixel-format defined.",
+                            default_pixfmt,
+                        )
                     )
-                )
-                output_params["-pix_fmt"] = default_pixfmt
 
-            # dynamically calculate raw-frame dtype based on pix format selected
-            frames_pixfmt = output_params["-pix_fmt"]
+            # dynamically calculate raw-frame datatype based on pixel-format selected
             (self.__raw_frame_depth, rawframesbpp) = [
                 (int(x[1]), int(x[2]))
                 for x in self.__ff_pixfmt_metadata
-                if x[0] == frames_pixfmt
+                if x[0] == rawframe_pixfmt
             ][0]
             raw_bit_per_component = rawframesbpp // self.__raw_frame_depth
-            if raw_bit_per_component in [4, 8]:
+            if 4 <= raw_bit_per_component <= 8:
                 self.__raw_frame_dtype = np.dtype("u1")
-            elif raw_bit_per_component == 16:
-                if frames_pixfmt.endswith("le"):
+            elif 8 < raw_bit_per_component <= 16 and rawframe_pixfmt.endswith(
+                ("le", "be")
+            ):
+                if rawframe_pixfmt.endswith("le"):
                     self.__raw_frame_dtype = np.dtype("<u2")
-                elif frames_pixfmt.endswith("be"):
-                    self.__raw_frame_dtype = np.dtype(">u2")
                 else:
-                    pass
+                    self.__raw_frame_dtype = np.dtype(">u2")
             else:
-                # reset to default if not supported
-                logger.critical(
-                    "Given `frame_format` value: {} is not supported by FFdecoder. Switching to default `{}`!".format(
-                        frames_pixfmt, "rgb24"
+                # reset to both pixel-format and datatype to default if not supported
+                not (self.__frame_format is None) and logger.warning(
+                    "Selected pixel-format `{}` dtype is not supported by FFdecoder API. Switching to default `rgb24` pixel-format!".format(
+                        rawframe_pixfmt
                     )
                 )
-                output_params["-pix_fmt"] = default_pixfmt
-                # change dtype
+                rawframe_pixfmt = "rgb24"
                 self.__raw_frame_dtype = np.dtype("u1")
-            # assign to global parameter
-            self.__raw_frame_pixfmt = output_params["-pix_fmt"]
-            # also store as metadata
-            self.__source_metadata["output_frames_pixfmt"] = output_params["-pix_fmt"]
-
-            # handle raw-frame size
-            if not (self.__custom_resolution is None):
-                # assign if assigned by user
+
+            # Check if not special case
+            if self.__frame_format != "null":
+                # assign to FFmpeg pipeline otherwise
+                output_params["-pix_fmt"] = rawframe_pixfmt
+            # assign to global parameter further usage
+            self.__raw_frame_pixfmt = rawframe_pixfmt
+            # also override as metadata(if available)
+            if "output_frames_pixfmt" in self.__sourcer_metadata:
+                self.__sourcer_metadata[
+                    "output_frames_pixfmt"
+                ] = self.__raw_frame_pixfmt
+
+            # handle raw-frame resolution
+            # notify FFmpeg `-s` parameter cannot be assigned directly
+            if "-s" in self.__extra_params:
+                logger.warning(
+                    "Discarding user-defined `-s` FFmpeg parameter as it can only be assigned with `-custom_resolution` attribute! Read docs for more details."
+                )
+                self.__extra_params.pop("-s", None)
+            # assign output rawframe resolution
+            if not (self.__custom_resolution is None) and not isinstance(
+                self.__custom_resolution, str
+            ):
+                # assign if assigned by user and not "null"(str)
                 self.__raw_frame_resolution = self.__custom_resolution
+                self.__verbose_logs and logger.info(
+                    "User-defined `{}` frame resolution will be used for this pipeline.".format(
+                        self.__raw_frame_resolution
+                    )
+                )
+            elif (
+                "output_frames_resolution"
+                in self.__sourcer_metadata  # means `scale` filter is defined
+                and self.__sourcer_metadata["output_frames_resolution"]
+                and len(self.__sourcer_metadata["output_frames_resolution"]) == 2
+            ):
+                # calculate raw-frame resolution/dimensions based on output.
+                self.__raw_frame_resolution = self.__sourcer_metadata[
+                    "output_frames_resolution"
+                ]
             elif (
-                self.__source_metadata["source_video_resolution"]
-                and len(self.__source_metadata["source_video_resolution"]) == 2
+                self.__sourcer_metadata["source_video_resolution"]
+                and len(self.__sourcer_metadata["source_video_resolution"]) == 2
             ):
-                # calculate raw-frame resolution/dimensions based on source (if not assigned by user).
-                self.__raw_frame_resolution = self.__source_metadata[
+                # calculate raw-frame resolution/dimensions based on source.
+                self.__raw_frame_resolution = self.__sourcer_metadata[
                     "source_video_resolution"
                 ]
             else:
                 # otherwise raise error
                 raise RuntimeError(
-                    "Invalid `source_video_resolution` metadata value detected!"
+                    "Both source and output metadata values found Invalid with {} `-custom_resolution` attribute. Aborting!".format(
+                        "null"
+                        if isinstance(self.__inputframerate, str)
+                        else "undefined"
+                    )
+                )
+            # special mode to discard `-size/-s` FFmpeg parameter completely
+            if isinstance(self.__custom_resolution, str):
+                logger.critical(
+                    "Manually discarding `-size/-s` FFmpeg parameter from this pipeline."
+                )
+            else:
+                # add to pipeline
+                dimensions = "{}x{}".format(
+                    self.__raw_frame_resolution[0], self.__raw_frame_resolution[1]
+                )
+                output_params["-s"] = str(dimensions)
+            # log if filters or default source is used
+            self.__verbose_logs and (
+                self.__custom_resolution is None
+                or isinstance(self.__custom_resolution, str)
+            ) and logger.info(
+                "{} for this pipeline for defining output resolution.".format(
+                    "FFmpeg filter values will be used"
+                    if "output_frames_resolution" in self.__sourcer_metadata
+                    else "Default source resolution will be used"
                 )
-            # add to pipeline
-            dimensions = "{}x{}".format(
-                self.__raw_frame_resolution[0], self.__raw_frame_resolution[1]
             )
-            output_params["-s"] = str(dimensions)
 
             # dynamically calculate raw-frame framerate based on source (if not assigned by user).
-            if self.__inputframerate > 0.0:
-                # assign if assigned by user
+            if (
+                not isinstance(self.__inputframerate, str)
+                and self.__inputframerate > 0.0
+            ):
+                # assign if assigned by user and not "null"(str)
                 output_params["-framerate"] = str(self.__inputframerate)
-            elif self.__source_metadata["source_video_framerate"] > 0.0:
-                # calculate raw-frame framerate based on source
-                output_params["-framerate"] = str(
-                    self.__source_metadata["source_video_framerate"]
+                self.__verbose_logs and logger.info(
+                    "User-defined `{}` output framerate will be used for this pipeline.".format(
+                        str(self.__inputframerate)
+                    )
+                )
+            elif (
+                "output_framerate"
+                in self.__sourcer_metadata  # means `fps` filter is defined
+                and self.__sourcer_metadata["output_framerate"] > 0.0
+            ):
+                # special mode to discard `-framerate/-r` FFmpeg parameter completely
+                if self.__inputframerate == "null":
+                    logger.critical(
+                        "Manually discarding `-framerate/-r` FFmpeg parameter from this pipeline."
+                    )
+                else:
+                    # calculate raw-frame framerate based on output
+                    output_params["-framerate"] = str(
+                        self.__sourcer_metadata["output_framerate"]
+                    )
+                self.__verbose_logs and logger.info(
+                    "FFmpeg filter values will be used for this pipeline for defining output framerate."
+                )
+            elif self.__sourcer_metadata["source_video_framerate"] > 0.0:
+                # special mode to discard `-framerate/-r` FFmpeg parameter completely
+                if self.__inputframerate == "null":
+                    logger.critical(
+                        "Manually disabling `-framerate/-r` FFmpeg parameter for this pipeline."
+                    )
+                else:
+                    # calculate raw-frame framerate based on source
+                    output_params["-framerate"] = str(
+                        self.__sourcer_metadata["source_video_framerate"]
+                    )
+                self.__verbose_logs and logger.info(
+                    "Default source framerate will be used for this pipeline for defining output framerate."
                 )
             else:
                 # otherwise raise error
                 raise RuntimeError(
-                    "Invalid `source_video_framerate` metadata value detected!"
+                    "Both source and output metadata values found Invalid with {} `-framerate` attribute. Aborting!".format(
+                        "null"
+                        if isinstance(self.__inputframerate, str)
+                        else "undefined"
+                    )
                 )
 
             # add rest to output parameters
@@ -452,8 +589,11 @@ def formulate(self):
             # TODO Added support for `-re -stream_loop` and `-loop`
             if "-frames:v" in input_params:
                 self.__raw_frame_num = input_params["-frames:v"]
-            elif self.__source_metadata["approx_video_nframes"]:
-                self.__raw_frame_num = self.__source_metadata["approx_video_nframes"]
+            elif (
+                not (self.__sourcer_metadata["approx_video_nframes"] is None)
+                and self.__sourcer_metadata["approx_video_nframes"] > 0
+            ):
+                self.__raw_frame_num = self.__sourcer_metadata["approx_video_nframes"]
             else:
                 self.__raw_frame_num = None
                 # log that number of frames are unknown
@@ -461,6 +601,13 @@ def formulate(self):
                     "Live/Network Stream detected! Number of frames in given source are not known."
                 )
 
+            # log Mode of Operation
+            self.__verbose_logs and logger.critical(
+                "Activating {} Mode of Operation.".format(
+                    self.__supported_opmodes[self.__opmode]
+                )
+            )
+
             # compose the Pipeline using formulated FFmpeg parameters
             self.__launch_FFdecoderline(input_params, output_params)
 
@@ -477,7 +624,7 @@ def __fetchNextfromPipeline(self):
         """
         assert not (
             self.__process is None
-        ), "Pipeline is not running! Check if you called `create()` method."
+        ), "Pipeline is not running! You must call `formulate()` method first."
 
         # formulated raw frame size
         raw_frame_size = (
@@ -496,7 +643,7 @@ def __fetchNextfromPipeline(self):
                 dtype=self.__raw_frame_dtype,
             )
         except Exception as e:
-            raise RuntimeError("Frame fetching failed with error: {}".format(str(e)))
+            raise RuntimeError("Frame buffering failed with error: {}".format(str(e)))
         return (
             nparray
             if not (nparray is None) and len(nparray) == raw_frame_size
@@ -513,7 +660,7 @@ def __fetchNextFrame(self):
         if frame is None:
             return frame
         elif self.__raw_frame_pixfmt.startswith("gray"):
-            # reconstruct gray frames
+            # reconstruct exclusive `gray` frames
             frame = frame.reshape(
                 (
                     self.__raw_frame_resolution[1],
@@ -521,15 +668,6 @@ def __fetchNextFrame(self):
                     self.__raw_frame_depth,
                 )
             )[:, :, 0]
-        elif self.__raw_frame_pixfmt == "yuv444p":
-            # reconstruct exclusive frames
-            frame = frame.reshape(
-                (
-                    self.__raw_frame_depth,
-                    self.__raw_frame_resolution[1],
-                    self.__raw_frame_resolution[0],
-                )
-            ).transpose((1, 2, 0))
         else:
             # reconstruct default frames
             frame = frame.reshape(
@@ -548,14 +686,14 @@ def generateFrame(self):
         _(also an Iterator using `next()`)_ of video frames, grabbed continuously from the buffer.
         """
         if self.__raw_frame_num is None or not self.__raw_frame_num:
-            while not self.__terminate_stream:
+            while not self.__terminate_stream:  # infinite raw frames
                 frame = self.__fetchNextFrame()
                 if frame is None:
                     self.__terminate_stream = True
-                    continue
+                    break
                 yield frame
         else:
-            for _ in range(self.__raw_frame_num):
+            for _ in range(self.__raw_frame_num):  # finite raw frames
                 frame = self.__fetchNextFrame()
                 if frame is None:
                     self.__terminate_stream = True
@@ -586,8 +724,15 @@ def metadata(self):
         # import dependency
         import json
 
-        # return complete (source+user-defined) metadata as JSON string
-        return json.dumps({**self.__source_metadata, **self.__user_metadata}, indent=2)
+        # return complete metadata information as JSON string
+        return json.dumps(
+            {
+                **self.__sourcer_metadata,  # source video
+                **self.__missing_prop,  # missing properties
+                **self.__user_metadata,  # user-defined
+            },
+            indent=2,
+        )
 
     @metadata.setter
     def metadata(self, value):
@@ -601,24 +746,61 @@ def metadata(self, value):
         if value and isinstance(value, dict):
             # log it
             self.__verbose_logs and logger.info("Updating Metadata...")
-            # extract any source metadata keys
-            default_keys = set(value).intersection(self.__source_metadata)
+            # extract any source and output internal metadata keys
+            default_keys = set(value).intersection(
+                {**self.__sourcer_metadata, **self.__missing_prop}
+            )
+            # counterpart source properties for each output properties
+            counterpart_prop = {
+                "output_frames_resolution": "source_video_resolution",
+                "output_frames_pixfmt": "source_video_pixfmt",
+                "output_framerate": "source_video_framerate",
+            }
             # iterate over source metadata keys and sanitize it
             for key in default_keys or []:
                 if key == "source":
-                    # `source` metadata value cannot be altered
+                    # metadata properties that cannot be altered
+                    logger.warning(
+                        "`{}` metadata property value cannot be altered. Discarding!".format(
+                            key
+                        )
+                    )
+                elif key in self.__missing_prop:
+                    # missing metadata properties are unavailable and read-only
+                    # notify user about alternative counterpart property (if available)
                     logger.warning(
-                        "`source` metadata value cannot be altered. Discarding!"
+                        "`{}` metadata property is read-only".format(key)
+                        + (
+                            ". Try updating `{}` property instead!".format(
+                                counterpart_prop[key]
+                            )
+                            if key in counterpart_prop.keys()
+                            else " and cannot be updated!"
+                        )
                     )
-                elif isinstance(value[key], type(self.__source_metadata[key])):
+                elif isinstance(value[key], type(self.__sourcer_metadata[key])):
                     # check if correct datatype as original
+                    self.__verbose_logs and logger.info(
+                        "Updating `{}`{} metadata property to `{}`.".format(
+                            key,
+                            " and its counterpart"
+                            if key in counterpart_prop.values()
+                            else "",
+                            value[key],
+                        )
+                    )
                     # update source metadata if valid
-                    self.__source_metadata.update(value)
-                    continue
+                    self.__sourcer_metadata[key] = value[key]
+                    # also update missing counterpart property (if available)
+                    counter_key = next(
+                        (k for k, v in counterpart_prop.items() if v == key), ""
+                    )
+                    if counter_key:
+                        self.__missing_prop[counter_key] = value[key]
                 else:
                     # otherwise discard and log it
                     logger.warning(
-                        "Manually assigned `{}` metadata value is invalid type. Discarding!"
+                        "Manually assigned `{}` metadata property value is of invalid type. Discarding!"
                     ).format(key)
                 # delete invalid key
                 del value[key]
@@ -626,7 +808,7 @@ def metadata(self, value):
             # Python's `json` module converts Python tuples to JSON lists
             # because that's the closest thing in JSON to a tuple.
             any(isinstance(value[x], tuple) for x in value) and logger.warning(
-                "All TUPLE metadata values will be converted to LIST datatype. Read docs for more details."
+                "All TUPLE metadata properties will be converted to LIST datatype. Read docs for more details."
             )
             # update user-defined metadata
             self.__user_metadata.update(value)
@@ -656,48 +838,49 @@ def __launch_FFdecoderline(self, input_params, output_params):
             + self.__ffmpeg_prefixes
             + input_parameters
             + (
-                ["-f", self.__source_metadata["source_demuxer"]]
-                if ("source_demuxer" in self.__source_metadata.keys())
+                ["-f", self.__sourcer_metadata["source_demuxer"]]
+                if ("source_demuxer" in self.__sourcer_metadata.keys())
                 else []
             )
-            + ["-i", self.__source_metadata["source"]]
+            + ["-i", self.__sourcer_metadata["source"]]
             + output_parameters
             + ["-f", "rawvideo", "-"]
         )
-        # assign value to class variable
-        _cmd = " ".join(cmd)
         # compose the FFmpeg process
         if self.__verbose_logs:
-            logger.debug("Executing FFmpeg command: `{}`".format(_cmd))
+            logger.debug("Executing FFmpeg command: `{}`".format(" ".join(cmd)))
             # In debugging mode
-            self.__process = sp.Popen(cmd, stdin=sp.PIPE, stdout=sp.PIPE, stderr=None)
+            self.__process = sp.Popen(
+                cmd, stdin=sp.DEVNULL, stdout=sp.PIPE, stderr=None
+            )
         else:
             # In silent mode
             self.__process = sp.Popen(
-                cmd, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.DEVNULL
+                cmd, stdin=sp.DEVNULL, stdout=sp.PIPE, stderr=sp.DEVNULL
             )
 
     def terminate(self):
         """
         Safely terminates all processes.
         """
+
         # signal we are closing
         self.__verbose_logs and logger.debug("Terminating FFdecoder Pipeline...")
         self.__terminate_stream = True
         # check if no process was initiated at first place
         if self.__process is None or not (self.__process.poll() is None):
-            logger.warning("Pipeline already terminated!")
+            logger.info("Pipeline already terminated.")
             return
         # Attempt to close pipeline.
         # close `stdin` output
         self.__process.stdin and self.__process.stdin.close()
         # close `stdout` output
         self.__process.stdout and self.__process.stdout.close()
-        # wait if still process is still processing some information
+        # terminate/kill process if still processing
         if self.__process.poll() is None:
-            self.__process.terminate()
+            # demuxers prefer kill
+            self.__process.kill()
+        # wait if not exiting
         self.__process.wait()
         self.__process = None
-        self.__verbose_logs and logger.debug(
-            "FFdecoder Pipeline terminated successfully"
-        )
+        logger.info("Pipeline terminated successfully.")
diff --git a/deffcode/ffhelper.py b/deffcode/ffhelper.py
index c71998b..10cb5ec 100644
--- a/deffcode/ffhelper.py
+++ b/deffcode/ffhelper.py
@@ -48,7 +48,7 @@ class TimeoutHTTPAdapter(HTTPAdapter):
     A custom Transport Adapter with default timeouts
     """
 
-    def __init__(self, *args, **kwargs):
+    def __init__(self, *args, **kwargs): 
         self.timeout = DEFAULT_TIMEOUT
         if "timeout" in kwargs:
             self.timeout = kwargs["timeout"]
@@ -350,6 +350,192 @@ def get_supported_demuxers(path):
     return [o.strip() if not ("," in o) else o.split(",")[-1].strip() for o in outputs]
 
 
+def extract_device_n_demuxer(path, machine_OS=None, verbose=False):
+    """
+    ## get_valid_devicepath
+
+    Discovers and extracts all Video-Capture device(s) name/path/index present on system and
+    supported by valid OS specific FFmpeg demuxer.
+
+    Parameters:
+        path (string): absolute path of FFmpeg binaries.
+        machine_OS(string): OS running _(Must be a value of `platform.system()` module)_.
+        verbose (bool): enables/disables verbose.
+
+    **Returns:** Tuple of list of supported device(s) path/name/index and OS specific demuxer used.
+    """
+    # validate `machine_OS` parameter value
+    assert not (machine_OS is None) and isinstance(
+        machine_OS, str
+    ), "`machine_OS` parameter value is empty or invalid type. Aborting!"
+
+    # initialize params
+    devices = []  # handles devices discovered
+    req_demuxer = None  # handle required demuxer
+
+    # define all valid FFmpeg demuxers w.r.t OS platforms
+    valid_demuxers = dict(Windows="dshow", Darwin="avfoundation", Linux="v4l2")
+
+    # check OS is supported
+    if not machine_OS.strip() in list(valid_demuxers.keys()):
+        # raise error if OS isn't supported
+        raise ValueError(
+            """Unsupported OS detected! The `source_demuxer='auto'` value isn't supported on your OS, 
+                Kindly assign `source` and `source_demuxer` parameter values manually."""
+        )
+    else:
+        # assign required demuxer
+        req_demuxer = valid_demuxers[machine_OS.strip()]
+
+    # log if specified
+    verbose and logger.debug("Auto-Searching for valid devices...")
+
+    # assert if demuxer is supported by provided ffmpeg.
+    assert req_demuxer in get_supported_demuxers(
+        path
+    ), "Required `{}` demuxer isn't supported by provided FFmpeg binaries. Kindly compile FFmpeg with \
+            suitable flags or manually assign `source` and `source_demuxer` parameter values. Aborting!".format(
+        valid_demuxers[machine_OS]
+    )
+    # create default ffmpeg command (for Windows and MacOS)
+    default_ffcommand = "-hide_banner -list_devices true -f {} -i dummy".format(
+        req_demuxer
+    )
+
+    # find all OS specific FFmpeg devices path and demuxer
+    if machine_OS == "Windows":
+        # get metadata
+        metadata = check_sp_output(
+            [path] + default_ffcommand.split(" "),
+            force_retrieve_stderr=True,
+        )
+        # clean and split metadata
+        splitted = [x.decode("utf-8").strip() for x in metadata.split(b"\n")]
+        # find video only
+        head, sep, tail = "\n".join(splitted).partition("DirectShow audio")
+        if head.strip():
+            # compile regex
+            finder = re.compile(r'"(.*?[^\\])"')
+            # find all outputs
+            outputs = finder.findall(head.strip())
+            # return output findings
+            devices = [o.strip() for o in outputs if not (o.startswith("@device"))]
+    elif machine_OS == "Linux":
+        # get devices if `video4linux` drivers are correctly configured.
+        metadata = check_sp_output(
+            ["v4l2-ctl", "--list-devices"],
+            force_retrieve_stderr=True,
+        )
+        # decode metadata
+        decoded = metadata.decode("utf-8").strip()
+        # check if command executed properly
+        if (
+            not decoded
+            or set(["command", "not", "found"]).issubset(decoded.split(" "))
+            or (
+                set(["Cannot", "open", "device"]).issubset(decoded.split(" "))
+                and not ("):" in decoded)
+            )
+        ):
+            logger.error(
+                "Cannot execute `v4l2-ctl` command. "
+                + (
+                    "Kindly install `v4l-utils` package on your linux machine."
+                    if set(["command", "not", "found"]).issubset(decoded.split(" "))
+                    else "Permission denied! Add your username to the `video` group to fix this error."
+                )
+            )
+        else:
+            # clean metadata
+            clean_n_splitted = [
+                x.strip()
+                for x in decoded.split("\n\n")
+                if "/dev/video" in x and "):" in x
+            ]
+            # compile regex
+            finder = re.compile(r"^[a-zA-Z0-9_.\- ]*")
+            # iterate over data
+            for data in clean_n_splitted:
+                # find all valid device names
+                device_name = [dev.strip() for dev in finder.findall(data) if dev]
+                dev_paths = [x.strip() for x in data.split("\n") if "/dev/video" in x]
+                # patch for multiple /dev/video paths for single device
+                if len(dev_paths) > 1:
+                    # warn users about this
+                    verbose and logger.warning(
+                        "Multiple `/dev/video` paths detected for {} device. This might take a while!".format(
+                            device_name
+                        )
+                    )
+                    # iterate over each device's paths
+                    for path in dev_paths:
+                        # search in path properties
+                        metadata_path = check_sp_output(
+                            ["v4l2-ctl", "--device={}".format(path), "--all"],
+                        )
+                        # decode path metadata
+                        decoded_path = metadata_path.decode("utf-8").strip()
+                        if (
+                            "Width/Height" in decoded_path
+                            and "Pixel Format" in decoded_path
+                        ):
+                            # append once required Width/Height and Pixel Format detected
+                            devices.append({path: device_name})
+                        else:
+                            # skip path otherwise
+                            pass
+                elif len(dev_paths) == 1:
+                    # append path directly if only one
+                    devices.append({dev_paths[0]: device_name})
+                else:
+                    pass
+    else:  # Darwin OSes
+        # get metadata
+        metadata = check_sp_output(
+            [path] + default_ffcommand.split(" "),
+            force_retrieve_stderr=True,
+        )
+        # clean and split metadata
+        splitted = [x.decode("utf-8").strip() for x in metadata.split(b"\n")]
+        # find video only
+        head, sep, tail = "\n".join(splitted).partition("AVFoundation audio")
+        if head.strip():
+            # compile regex
+            finder = re.compile(r"\[[0-9]\](.*)")
+            # find all outputs
+            outputs = finder.findall(head)
+            # return output findings
+            devices = [o.strip() for o in outputs]
+
+    # check if any devices were found
+    if devices:
+        # log everything if `verbose=True`
+        if verbose:
+            for idx, dev in enumerate(devices):
+                logger.info(
+                    "[{}]: {}".format(
+                        idx,
+                        dev
+                        if machine_OS != "Linux"
+                        else "{} at path `{}`".format(
+                            next(iter(dev.values()))[0], next(iter(dev.keys()))
+                        ),
+                    )
+                )
+            logger.debug(
+                "Auto-Search completed successfully! Found `{}` valid device(s).".format(
+                    len(devices)
+                )
+            )
+        # return list of device name/path/index and related demuxer
+        return (devices, req_demuxer)
+    else:
+        # otherwise raise error
+        raise RuntimeError(
+            "API unable to discover any valid device(s) connected your machine. Aborting!"
+        )
+
+
 def validate_imgseqdir(source, extension="jpg", verbose=False):
     """
     ## validate_imgseqdir
@@ -488,6 +674,7 @@ def check_sp_output(*args, **kwargs):
     retcode = process.poll()
     # handle return code
     if retcode and not (retrieve_stderr):
+        logger.error("[Pipline-Error] :: {}".format(output.decode("utf-8")))
         cmd = kwargs.get("args")
         if cmd is None:
             cmd = args[0]
@@ -496,7 +683,9 @@ def check_sp_output(*args, **kwargs):
         raise error
     # raise error if no output
     bool(output) or bool(stderr) or logger.error(
-        "FFmpeg Pipline failed to exact any metadata!"
+        "[Pipline-Error] :: Pipline failed to exact any data from command: {}!".format(
+            args[0] if args else []
+        )
     )
     # return output otherwise
-    return output if not (retrieve_stderr) else stderr
+    return stderr if retrieve_stderr and stderr else output
diff --git a/deffcode/sourcer.py b/deffcode/sourcer.py
index 268be52..b22b166 100644
--- a/deffcode/sourcer.py
+++ b/deffcode/sourcer.py
@@ -21,19 +21,21 @@
 # import required libraries
 import re
 import os
+import copy
 import json
 import logging
 import platform
 import numpy as np
 
 # import utils packages
-from .utils import logger_handler
+from .utils import logger_handler, validate_device_index, dict2Args
 from .ffhelper import (
     check_sp_output,
     get_supported_demuxers,
     is_valid_url,
     is_valid_image_seq,
     get_valid_ffmpeg_path,
+    extract_device_n_demuxer,
 )
 
 # define logger
@@ -73,7 +75,7 @@ def __init__(
         source_demuxer=None,
         custom_ffmpeg="",
         verbose=False,
-        **sourcer_params
+        **sourcer_params,
     ):
         """
         This constructor method initializes the object state and attributes of the Sourcer Class.
@@ -86,7 +88,7 @@ def __init__(
             sourcer_params (dict): provides the flexibility to control supported internal and FFmpeg parameters.
         """
         # checks if machine in-use is running windows os or not
-        self.__os_windows = True if os.name == "nt" else False
+        self.__machine_OS = platform.system()
 
         # define internal parameters
         self.__verbose_logs = (  # enable verbose if specified
@@ -99,7 +101,7 @@ def __init__(
         # sanitize sourcer_params
         self.__sourcer_params = {
             str(k).strip(): str(v).strip()
-            if not isinstance(v, (dict, list, int, float))
+            if not isinstance(v, (dict, list, int, float, tuple))
             else v
             for k, v in sourcer_params.items()
         }
@@ -133,7 +135,7 @@ def __init__(
         # validate the FFmpeg assets and return location (also downloads static assets on windows)
         self.__ffmpeg = get_valid_ffmpeg_path(
             str(custom_ffmpeg),
-            self.__os_windows,
+            True if self.__machine_OS == "Windows" else False,
             ffmpeg_download_path=__ffmpeg_download_path,
             verbose=self.__verbose_logs,
         )
@@ -149,30 +151,75 @@ def __init__(
                 "[DeFFcode:ERROR] :: Failed to find FFmpeg assets on this system. Kindly compile/install FFmpeg or provide a valid custom FFmpeg binary path!"
             )
 
-        # define externally accessible parameters
-        self.__source = source  # handles source stream
+        # sanitize externally accessible parameters and assign them
         # handles source demuxer
-        self.__source_demuxer = (
-            source_demuxer.strip().lower() if isinstance(source_demuxer, str) else None
-        )
-        # handles source stream extension
-        self.__source_extension = os.path.splitext(source)[-1]
-        self.__default_video_resolution = ""  # handle stream resolution
-        self.__default_video_framerate = ""  # handle stream framerate
-        self.__default_video_bitrate = ""  # handle stream's video bitrate
-        self.__default_video_pixfmt = ""  # handle stream's video pixfmt
-        self.__default_video_decoder = ""  # handle stream's video decoder
-        self.__default_source_duration = ""  # handle stream's video duration
-        self.__approx_video_nframes = ""  # handle approx stream frame number
-        self.__default_audio_bitrate = ""  # handle stream's audio bitrate
-        self.__default_audio_samplerate = ""  # handle stream's audio samplerate
-
-        # handle flags
-        self.__contains_video = False  # contain video
-        self.__contains_audio = False  # contain audio
-        self.__contains_images = False  # contain image-sequence
-
-        # check whether metadata probed or not
+        if source is None:
+            # first check if source value is empty
+            # raise error if true
+            raise ValueError("Input `source` parameter is empty!")
+        elif isinstance(source_demuxer, str):
+            # assign if valid demuxer value
+            self.__source_demuxer = source_demuxer.strip().lower()
+            # assign if valid demuxer value
+            assert self.__source_demuxer != "auto" or validate_device_index(
+                source
+            ), "Invalid `source_demuxer='auto'` value detected with source: `{}`. Aborting!".format(
+                source
+            )
+        else:
+            # otherwise find valid default source demuxer value
+            # enforce "auto" if valid index device
+            self.__source_demuxer = "auto" if validate_device_index(source) else None
+            # log if not valid index device and invalid type
+            self.__verbose_logs and not self.__source_demuxer in [
+                "auto",
+                None,
+            ] and logger.warning(
+                "Discarding invalid `source_demuxer` parameter value of wrong type: `{}`".format(
+                    type(source_demuxer).__name__
+                )
+            )
+            # log if not valid index device and invalid type
+            self.__verbose_logs and self.__source_demuxer == "auto" and logger.critical(
+                "Given source `{}` is a valid device index. Enforcing 'auto' demuxer.".format(
+                    source
+                )
+            )
+
+        # handles source stream
+        self.__source = source
+
+        # creates shallow copy for further usage #TODO
+        self.__source_org = copy.copy(self.__source)
+        self.__source_demuxer_org = copy.copy(self.__source_demuxer)
+
+        # handles all extracted devices names/paths list
+        # when source_demuxer = "auto"
+        self.__extracted_devices_list = []
+
+        # various source stream params
+        self.__default_video_resolution = ""  # handles stream resolution
+        self.__default_video_framerate = ""  # handles stream framerate
+        self.__default_video_bitrate = ""  # handles stream's video bitrate
+        self.__default_video_pixfmt = ""  # handles stream's video pixfmt
+        self.__default_video_decoder = ""  # handles stream's video decoder
+        self.__default_source_duration = ""  # handles stream's video duration
+        self.__approx_video_nframes = ""  # handles approx stream frame number
+        self.__default_audio_bitrate = ""  # handles stream's audio bitrate
+        self.__default_audio_samplerate = ""  # handles stream's audio samplerate
+
+        # handle various stream flags
+        self.__contains_video = False  # contains video
+        self.__contains_audio = False  # contains audio
+        self.__contains_images = False  # contains image-sequence
+
+        # handles output parameters through filters
+        self.__metadata_output = None  # handles output stream metadata
+        self.__output_frames_resolution = ""  # handles output stream resolution
+        self.__output_framerate = ""  # handles output stream framerate
+        self.__output_frames_pixfmt = ""  # handles output frame pixel format
+
+        # check whether metadata probed or not?
         self.__metadata_probed = False
 
     def probe_stream(self, default_stream_indexes=(0, 0)):
@@ -204,10 +251,26 @@ def probe_stream(self, default_stream_indexes=(0, 0)):
         if video_rfparams:
             self.__default_video_resolution = video_rfparams["resolution"]
             self.__default_video_framerate = video_rfparams["framerate"]
-        # parse pixel format
+
+        # parse output parameters through filters (if available)
+        if not (self.__metadata_output is None):
+            # parse output resolution and framerate
+            out_video_rfparams = self.__extract_resolution_framerate(
+                default_stream=default_stream_indexes[0], extract_output=True
+            )
+            if out_video_rfparams:
+                self.__output_frames_resolution = out_video_rfparams["resolution"]
+                self.__output_framerate = out_video_rfparams["framerate"]
+            # parse output pixel-format
+            self.__output_frames_pixfmt = self.__extract_video_pixfmt(
+                default_stream=default_stream_indexes[0], extract_output=True
+            )
+
+        # parse pixel-format
         self.__default_video_pixfmt = self.__extract_video_pixfmt(
             default_stream=default_stream_indexes[0]
         )
+
         # parse video decoder
         self.__default_video_decoder = self.__extract_video_decoder(
             default_stream=default_stream_indexes[0]
@@ -256,38 +319,44 @@ def probe_stream(self, default_stream_indexes=(0, 0)):
         # return reference to the instance object.
         return self
 
-    def retrieve_metadata(self, pretty_json=False):
+    def retrieve_metadata(self, pretty_json=False, force_retrieve_missing=False):
         """
         This method returns Parsed/Probed Metadata of the given source.
 
         Parameters:
             pretty_json (bool): whether to return metadata as JSON string(if `True`) or Dictionary(if `False`) type?
+            force_retrieve_output (bool): whether to also return metadata missing in current Pipeline. This method returns `(metadata, metadata_missing)` tuple if `force_retrieve_output=True` instead of `metadata`.
 
-        **Returns:** metadata formatted as JSON string or python dictionary.
+        **Returns:** `metadata` or `(metadata, metadata_missing)`, formatted as JSON string or python dictionary.
         """
         # check if metadata has been probed or not
         assert (
             self.__metadata_probed
         ), "Source Metadata not been probed yet! Check if you called `probe_stream()` method."
         # log it
-        self.__verbose_logs and logger.debug("Retrieving Metadata...")
+        self.__verbose_logs and logger.debug("Extracting Metadata...")
         # create metadata dictionary from information populated in private class variables
         metadata = {
             "ffmpeg_binary_path": self.__ffmpeg,
             "source": self.__source,
         }
+        metadata_missing = {}
         # Only either `source_demuxer` or `source_extension` attribute can be
         # present in metadata.
-        metadata.update(
-            {"source_extension": self.__source_extension}
-            if self.__source_demuxer is None
-            else {"source_demuxer": self.__source_demuxer}
-        )
+        if self.__source_demuxer is None:
+            metadata.update({"source_extension": os.path.splitext(self.__source)[-1]})
+            # update missing
+            force_retrieve_missing and metadata_missing.update({"source_demuxer": ""})
+        else:
+            metadata.update({"source_demuxer": self.__source_demuxer})
+            # update missing
+            force_retrieve_missing and metadata_missing.update({"source_extension": ""})
+        # add source video metadata properties
         metadata.update(
             {
                 "source_video_resolution": self.__default_video_resolution,
-                "source_video_framerate": self.__default_video_framerate,
                 "source_video_pixfmt": self.__default_video_pixfmt,
+                "source_video_framerate": self.__default_video_framerate,
                 "source_video_decoder": self.__default_video_decoder,
                 "source_duration_sec": self.__default_source_duration,
                 "approx_video_nframes": (
@@ -303,8 +372,59 @@ def retrieve_metadata(self, pretty_json=False):
                 "source_has_image_sequence": self.__contains_images,
             }
         )
-        # return metadata as either JSON string or Python dictionary
-        return json.dumps(metadata, indent=2) if pretty_json else metadata
+        # add output metadata properties (if available)
+        if not (self.__metadata_output is None):
+            metadata.update(
+                {
+                    "output_frames_resolution": self.__output_frames_resolution,
+                    "output_frames_pixfmt": self.__output_frames_pixfmt,
+                    "output_framerate": self.__output_framerate,
+                }
+            )
+        else:
+            # since output stream metadata properties are only available when additional
+            # FFmpeg parameters(such as filters) are defined manually, thereby missing
+            # output stream properties are handled by assigning them counterpart source
+            # stream metadata property values
+            force_retrieve_missing and metadata_missing.update(
+                {
+                    "output_frames_resolution": self.__default_video_resolution,
+                    "output_frames_pixfmt": self.__default_video_pixfmt,
+                    "output_framerate": self.__default_video_framerate,
+                }
+            )
+        # log it
+        self.__verbose_logs and logger.debug(
+            "Metadata Extraction completed successfully!"
+        )
+        # parse as JSON string(`json.dumps`), if defined
+        metadata = json.dumps(metadata, indent=2) if pretty_json else metadata
+        metadata_missing = (
+            json.dumps(metadata_missing, indent=2) if pretty_json else metadata_missing
+        )
+        # return `metadata` or `(metadata, metadata_missing)`
+        return metadata if not force_retrieve_missing else (metadata, metadata_missing)
+
+    @property
+    def enumerate_devices(self):
+        """
+        A property object that enumerate all probed Camera Devices connected to your system names
+        along with their respective "device indexes" or "camera indexes" as python dictionary.
+
+        **Returns:** Probed Camera Devices as python dictionary.
+        """
+        # check if metadata has been probed or not
+        assert (
+            self.__metadata_probed
+        ), "Source Metadata not been probed yet! Check if you called `probe_stream()` method."
+
+        # log if specified
+        self.__verbose_logs and logger.debug("Enumerating all probed Camera Devices.")
+
+        # return probed Camera Devices as python dictionary.
+        return {
+            dev_idx: dev for dev_idx, dev in enumerate(self.__extracted_devices_list)
+        }
 
     def __validate_source(self, source, source_demuxer=None, forced_validate=False):
         """
@@ -316,16 +436,88 @@ def __validate_source(self, source, source_demuxer=None, forced_validate=False):
 
         **Returns:** `True` if passed tests else `False`.
         """
+        # validate source demuxer(if defined)
+        if not (source_demuxer is None):
+            # check if "auto" demuxer is specified
+            if source_demuxer == "auto":
+                # integerise source to get index
+                index = int(source)
+                # extract devices list and actual demuxer value
+                (
+                    self.__extracted_devices_list,
+                    source_demuxer,
+                ) = extract_device_n_demuxer(
+                    self.__ffmpeg,
+                    machine_OS=self.__machine_OS,
+                    verbose=self.__verbose_logs,
+                )
+                # valid indexes range
+                valid_indexes = [
+                    x
+                    for x in range(
+                        -len(self.__extracted_devices_list),
+                        len(self.__extracted_devices_list),
+                    )
+                ]
+                # check index is within valid range
+                if self.__extracted_devices_list and index in valid_indexes:
+                    # overwrite actual source device name/path/index
+                    if self.__machine_OS == "Windows":
+                        # Windows OS requires "video=" suffix
+                        self.__source = source = "video={}".format(
+                            self.__extracted_devices_list[index]
+                        )
+                    elif self.__machine_OS == "Darwin":
+                        # Darwin OS requires only device indexes
+                        self.__source = source = (
+                            str(index)
+                            if index >= 0
+                            else str(len(self.__extracted_devices_list) + index)
+                        )
+                    else:
+                        # Linux OS require /dev/video format
+                        self.__source = source = next(
+                            iter(self.__extracted_devices_list[index].keys())
+                        )
+                    # overwrite source_demuxer global variable
+                    self.__source_demuxer = source_demuxer
+                    self.__verbose_logs and logger.debug(
+                        "Successfully configured device `{}` at index `{}` with demuxer `{}`.".format(
+                            self.__extracted_devices_list[index]
+                            if self.__machine_OS != "Linux"
+                            else next(
+                                iter(self.__extracted_devices_list[index].values())
+                            )[0],
+                            index
+                            if index >= 0
+                            else len(self.__extracted_devices_list) + index,
+                            self.__source_demuxer,
+                        )
+                    )
+                else:
+                    # raise error otherwise
+                    raise ValueError(
+                        "Given source `{}` is not a valid device index. Possible values index values can be: {}".format(
+                            source,
+                            ",".join(f"{x}" for x in valid_indexes),
+                        )
+                    )
+            # otherwise validate against supported demuxers
+            elif not (source_demuxer in get_supported_demuxers(self.__ffmpeg)):
+                # raise if fails
+                raise ValueError(
+                    "Installed FFmpeg failed to recognize `{}` demuxer. Check `source_demuxer` parameter value again!".format(
+                        source_demuxer
+                    )
+                )
+            else:
+                pass
+
         # assert if valid source
         assert source and isinstance(
             source, str
-        ), "Input source is empty or invalid type!"
-        # assert if valid source demuxer
-        assert source_demuxer is None or source_demuxer in get_supported_demuxers(
-            self.__ffmpeg
-        ), "Installed FFmpeg failed to recognise `{}` demuxer. Check ``source_demuxer`` parameter value again!".format(
-            source_demuxer
-        )
+        ), "Input `source` parameter is of invalid type!"
+
         # Differentiate input
         if forced_validate:
             source_demuxer is None and logger.critical(
@@ -345,17 +537,41 @@ def __validate_source(self, source, source_demuxer=None, forced_validate=False):
             logger.error("`source` value is unusable or unsupported!")
             # discard the value otherwise
             raise ValueError("Input source is invalid. Aborting!")
-        # extract metadata
-        metadata = check_sp_output(
-            [self.__ffmpeg]
-            + (["-hide_banner"] if not self.__verbose_logs else [])
-            + self.__ffmpeg_prefixes
-            + (["-f", source_demuxer] if source_demuxer else [])
-            + ["-i", source],
-            force_retrieve_stderr=True,
+        # format command
+        if self.__sourcer_params:
+            # handle additional params separately
+            meta_cmd = (
+                [self.__ffmpeg]
+                + (["-hide_banner"] if not self.__verbose_logs else [])
+                + ["-t", "0.0001"]
+                + self.__ffmpeg_prefixes
+                + (["-f", source_demuxer] if source_demuxer else [])
+                + ["-i", source]
+                + dict2Args(self.__sourcer_params)
+                + ["-f", "null", "-"]
+            )
+        else:
+            meta_cmd = (
+                [self.__ffmpeg]
+                + (["-hide_banner"] if not self.__verbose_logs else [])
+                + self.__ffmpeg_prefixes
+                + (["-f", source_demuxer] if source_demuxer else [])
+                + ["-i", source]
+            )
+        # extract metadata, decode, and filter
+        metadata = (
+            check_sp_output(
+                meta_cmd,
+                force_retrieve_stderr=True,
+            )
+            .decode("utf-8")
+            .strip()
         )
-        # filter and return
-        return metadata.decode("utf-8").strip()
+        # separate input and output metadata (if available)
+        if "Output #" in metadata:
+            (metadata, self.__metadata_output) = metadata.split("Output #")
+        # return metadata based on params
+        return metadata
 
     def __extract_video_bitrate(self, default_stream=0):
         """
@@ -419,7 +635,7 @@ def __extract_video_decoder(self, default_stream=0):
                 return filtered_pixfmt[0].split(" ")[-1]
         return ""
 
-    def __extract_video_pixfmt(self, default_stream=0):
+    def __extract_video_pixfmt(self, default_stream=0, extract_output=False):
         """
         This Internal method parses default video-stream pixel-format from metadata.
 
@@ -429,11 +645,19 @@ def __extract_video_pixfmt(self, default_stream=0):
         **Returns:** Default Video pixel-format as string value.
         """
         identifiers = ["Video:", "Stream #"]
-        meta_text = [
-            line.strip()
-            for line in self.__ffsp_output.split("\n")
-            if all(x in line for x in identifiers)
-        ]
+        meta_text = (
+            [
+                line.strip()
+                for line in self.__ffsp_output.split("\n")
+                if all(x in line for x in identifiers)
+            ]
+            if not extract_output
+            else [
+                line.strip()
+                for line in self.__metadata_output.split("\n")
+                if all(x in line for x in identifiers)
+            ]
+        )
         if meta_text:
             selected_stream = meta_text[
                 default_stream
@@ -493,21 +717,31 @@ def __extract_audio_bitrate_nd_samplerate(self, default_stream=0):
             )
         return result if result and (len(result) == 2) else {}
 
-    def __extract_resolution_framerate(self, default_stream=0):
+    def __extract_resolution_framerate(self, default_stream=0, extract_output=False):
         """
         This Internal method parses default video-stream resolution and framerate from metadata.
 
         Parameters:
             default_stream (int): selects specific audio-stream in case of multiple ones.
+            extract_output (bool): Whether to extract from output(if true) or input(if false) stream?
 
         **Returns:** Default Video resolution and framerate as dictionary value.
         """
         identifiers = ["Video:", "Stream #"]
-        meta_text = [
-            line.strip()
-            for line in self.__ffsp_output.split("\n")
-            if all(x in line for x in identifiers)
-        ]
+        # use output metadata if available
+        meta_text = (
+            [
+                line.strip()
+                for line in self.__ffsp_output.split("\n")
+                if all(x in line for x in identifiers)
+            ]
+            if not extract_output
+            else [
+                line.strip()
+                for line in self.__metadata_output.split("\n")
+                if all(x in line for x in identifiers)
+            ]
+        )
         result = {}
         if meta_text:
             selected_stream = meta_text[
diff --git a/deffcode/utils.py b/deffcode/utils.py
index 80951ed..8e477dc 100644
--- a/deffcode/utils.py
+++ b/deffcode/utils.py
@@ -78,7 +78,7 @@ def logger_handler():
 
 
 # define logger
-logger = logging.getLogger("Utilies")
+logger = logging.getLogger("Utilities")
 logger.propagate = False
 logger.addHandler(logger_handler())
 logger.setLevel(logging.DEBUG)
@@ -132,3 +132,32 @@ def delete_file_safe(file_path):
             dfile.exists() and dfile.unlink()
     except Exception as e:
         logger.exception(str(e))
+
+
+def validate_device_index(index):
+    """
+    ## validate_device_index
+
+    Validates if given device index is valid or not? Only Integers or String of integers are valid indexes.
+
+    Parameters:
+        index (int/str): Index of the device
+
+    **Returns:** A boolean value, confirming whether valid, or not?.
+    """
+    # validate index value
+    if isinstance(index, int):
+        # return true
+        return True
+    elif isinstance(index, str):
+        # remove any whitespaces
+        index.replace(" ", "")
+        # return true
+        return (
+            True
+            if (index.isnumeric() or (index.startswith("-") and index[1:].isnumeric()))
+            else False
+        )
+    else:
+        # return false otherwise
+        return False
diff --git a/deffcode/version.py b/deffcode/version.py
index d31c31e..788da1f 100644
--- a/deffcode/version.py
+++ b/deffcode/version.py
@@ -1,1 +1,1 @@
-__version__ = "0.2.3"
+__version__ = "0.2.4"
diff --git a/docs/changelog.md b/docs/changelog.md
index b24a927..5ae9747 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -20,12 +20,217 @@ limitations under the License.
 
 # Release Notes
 
+## v0.2.4 (In progress) :material-new-box:
 
-## v0.2.3 (2022-08-11) :material-new-box:
+??? new "New Features"
+    - [x] **FFdecoder API:**
+        * 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).
+                * 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.
+                * 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.
+                * 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.
+    - [x] **Sourcer API:**
+        * Implemented new comprehensive approach to handle `source_demuxer` parameter w.r.t  different `source` parameter values.
+            * The `source_demuxer` parameter now accepts "auto" as its value for enabling Index based Camera Device Capture feature in Sourcer API.
+            * Sourcer API auto-enforces `source_demuxer="auto"` by default, whenever a valid device index (uses `validate_device_index` method for validation) is provided as its `source` parameter value.
+                * ⚠️ Sourcer API will throw `Assertion` error if `source_demuxer="auto"` is provided explicitly without a valid device index at its `source` parameter.
+            * Source API now accepts all +ve and -ve device indexes (e.g. `-1,0,1,2` etc.) to its `source` parameter, both as in integer and string of integer types as source in Index based Camera Device Capture feature.
+                * Sourcer API imports and utilizes `extract_device_n_demuxer()` method for discovering and extracting all Video-Capture device(s) name/path/index present on system. 
+                    * ⚠️ Sourcer API will throw `RuntimeError` on failure to identify any device.
+                * Sourcer API auto verifies that the specified source device index is in range of the devices discovered. 
+                    * ⚠️ Sourcer API will raise `ValueError` if value goes out of valid range.
+                * Sourcer API also automatically handle -ve indexes if specified within the valid range.
+                * Implemented patch to auto-add `video=` suffix to selected device name before using it as video source on Windows OSes.
+                * Added patch for handling dictionary of devices paths(with devices names as values) and log messages on Linux Oses.
+                * Added `copy` import for shallow copying various class parameters.
+            * Implemented new 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` datatype to `sourcer_params` exception.
+            * Added `dict2Args` import. 
+        * Added `enumerate_devices` property object to enumerate all probed Camera Devices connected to a system names along with their respective "device indexes" or "camera indexes" as python dictionary.
+        * 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
+    - [x] **FFhelper:**
+        * Implemented new `extract_device_n_demuxer()` method for discovering and extracting all Video-Capture device(s) name/path/index present on system and supported by valid OS specific FFmpeg demuxer.
+            * Added support for three OS specific FFmpeg demuxers: namely `dshow` for Windows, `v4l2` for Linux, and `avfoundation` for Darwin/Mac OSes.
+            * Implemented separate code for parsing outputs of python `subprocess` module outputs provided with different commands for discovering all Video-Capture devices present on system.
+                * Processed `dshow` _(on Windows)_ and `avfoundation` _(on Darwin)_ demuxers in FFmpeg commands with `-list_devices true` parameters using `subprocess` module and applied various brute-force pattern matching on its output for discovering and extracting all devices names/indexes.
+                * Used `v4l2-ctl` submodule command on Linux machines for listing all Video-Capture devices using `subprocess` module and applied various brute-force pattern matching on its output for discovering and extracting all devices names and true system `/dev/video` paths.
+                    * Added patch for a single device with multiple `/dev/video` paths _(each for metadata, video, controls)_, where it iterates on each path to find the exact path that contains valid video stream. 
+                    * Added elaborated checks for catching all possible system errors that can occur while running `v4l2-ctl` submodule command.
+                    * The method will return discovered devices as list of dictionaries with device paths(`/dev/video`) as keys and respective device name as the values, instead of default list of device names.
+                    * Added patch for handling Linux specific log messages.
+            * Added various logging messages to notify users about all discover devices names/paths w.r.t indexes.
+            * ⚠️ The `extract_device_n_demuxer` method will raise `RuntimeError` if it fails to identify any device.
+            * Added various checks to assert invalid input parameters and unsupported OSes.
+            * Added `machine_OS` parameter to specify OS running on the system, must be value of `platform.system()` module. If invalid the method will raise ValueError.
+    - [x] **Utilities:** 
+        * Added new `new validate_device_index()` method to verify if given device index is valid or not?
+            * Only Integers or String of integers are valid indexes. 
+            * Returns a boolean value, confirming whether valid(If `true`), or not(If `False`).
+        * Added checks to support all +ve and -ve integers, both as integer and string types.
+    - [x] **Docs:**
+        * Added `new validate_device_index()` method and its parameters description.
+        * Added `new extract_device_n_demuxer()` method and its parameters description.
+        * Added Decoding Camera Devices using Indexes support docs.
+            * Added `decode-camera-devices.md` doc for Decoding Camera Devices using Indexes.
+                * Added `Enumerating all Camera Devices with Indexes` example doc with code.
+                * Added `Capturing and Previewing frames from a Camera using Indexes` example doc with code.
+            * Added Camera Device Index support docs to FFdecoder and Sourcer API params.
+    - [x] **CI:**
+        * Added check exception for `mandelbrot` virtual source in Sourcer API's `test_probe_stream_n_retrieve_metadata` unittest.
+        * Added new `test_discard_n_filter_params` unittest for test recently added supported for both discarded parameters and filter values.
+
+??? success "Updates/Improvements" 
+    - [x] FFdecoder API:
+        * 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.
+            * `output_frames_pixfmt` metadata property(if available) will be overridden to `rgb24`.
+        * Replaced `continue` with `break` in `generateFrame()` method.
+        * Improved handling of `frame_format` parameter.
+    - [x] Sourcer API:
+        * Simplified JSON formatting and returning values logic.
+        * Updated logging messages text and position.
+        * Removed redundant variable definitions.
+        * Changed related internal variable names w.r.t metadata property names.
+        * Replaced `os_windows` internal parameter with `machine_OS`, and changed its input from `os.name` to more flexible `platform.system()`. 
+        * Removed `source_extension` internal parameter and assigned values directly.
+    - [x] FFhelper:
+        * Implemented more robust pattern matching for Linux machines.
+        * Updated logs in `check_sp_output()` method for improving error output message.
+        * Implemented "Cannot open device" v4l2-ctl command Error logs. 
+    - [x] Maintenance: 
+        * Bumped version to `0.2.4`.
+        * Updated code comments.
+    - [x] CI:
+        * Updated FFdecoder API's `test_camera_capture` unittest to test new Index based Camera Device Capturing on different platforms.
+            * Added various parametrize `source` and `source_demuxer` parameter data to attain maximum coverage.
+            * Added `result` field to `fail` and `xfail` unittest according to parametrize data provided on different platforms.
+            * Removed `pytest.mark.skipif` to support all platforms.
+        * Added and updated various parametrize test data to attain maximum coverage.
+        * Limited range of extracted frames, for finishing tests faster.
+        * Updated unittests to reflect recent name changes.
+        * Disabled capturing of stdout/stderr with `-s` flag in pytest. 
+    - [x] Setup:
+        * Updated description metadata. 
+    - [x] Bash Script: 
+        * Created undeleteable `undelete.txt` file for testing on Linux envs.
+        * Updated `undelete.txt` file path.
+        * Made FFmpeg output less verbose.
+    - [x] 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 both basic and advanced project Index hyperlinks.
+          * Moved `decoding-live-feed-devices.md` doc from basic to advanced directory.
+          * Updated page navigation in `mkdocs.yml`.
+        * Update announcement bar to feature Index based Camera Device Capture support.
+        * Updated Project description and Key features of DeFFcode.
+        * Updated README.md with latest information.
+        * Updated `source` and `source_demuxer` param doc.
+        * Updated Hardware-Acceleration docs.
+            * Updated Hardware-Accelerated Video Decoding and Transcoding docs to inform users about DeFFcode generated YUV frames not yet supported by OpenCV and its APIs.
+        * Updated recipes docs to reflect recent changes in APIs. 
+        * Updated parameter docs to reflect recent name changes.
+        * Updated parameters/attributes introductory descriptions.
+        * Updated various parametrize data to attain maximum coverage. 
+        * Updated Zenodo badge and the BibTeX entry.
+        * Updated method description texts and logging messages.
+        * Update title headings, icons and admonition messages.
+        * Updated code comments.
+        * Updated `changelog.md`.
+
+
+??? danger "Breaking Updates/Changes"
+    * **API:**
+        - [x] :skull_crossbones: Implemented new Index based Camera Device Capture feature (Similar to OpenCV), where the user just have to assign device index as integer _(`-n` to `n-1`)_ in source parameter of DeFFcode APIs to directly access the given input device in few seconds.
+    * **FFdecoder API**
+        - [x] :skull_crossbones: Unsupported dtype pixel-format always defaults to `rgb24`.
+    * **Sourcer API:**
+        - [x] :skull_crossbones: Renamed `output_video_resolution` metadata property to `output_frames_resolution`.
+        - [x] :skull_crossbones: Renamed `output_video_framerate` metadata property to `output_framerate`.
+
+??? bug "Bug-fixes"
+    - [x] FFdecoder API:
+        * 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 w.r.t counterpart source property.
+                * 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.
+        * Fixed `av_interleaved_write_frame(): broken pipe` warning bug by switching `process.terminate()` with `process.kill()`.
+        * Fixed `AttributeError` bug caused due to typo in logger.
+    - [x] FFhelper:
+        * Fixed `check_sp_output()` method returning Standard Error (stderr) even when Nonetype.
+        * Fixed logger requiring `utf-8` decoding.
+        * Fixed missing `force_retrieve_stderr` argument to `check_sp_output` in `extract_device_n_demuxer` method on Linux platforms.
+        * Fixed logger message bug. 
+    - [x] Utils: 
+        * Fixed logger name typo.
+    - [x] Maintenance:
+        * Fixed hyperlinks to new GitHub's form schemas. 
+        * Fixed typos in logs messages.
+        * Removed redundant code.
+        * Updated code comments.
+    - [x] Setup:
+        * Rearranged `long_description` patches to address unused patch bug.
+    - [x] Bash Script:
+        * Fixed `chattr: No such file or directory` bug.
+    - [x] CI:
+        * Fixed missing `lavfi` demuxer for `mandelbrot` virtual source in Sourcer API's `test_probe_stream_n_retrieve_metadata` unittest.
+        * Fixed missing `ffparams` parameter bug in `test_discard_n_filter_params()` unittest.
+        * Fixed `test_camera_capture` test.
+        * Removed redundant similar `ValueError` checks.
+        * Fixed typo in pytest arguments.
+        * Fixed missing arguments.
+    - [x] Docs:
+        * Fixed invalid hyperlinks in ReadMe.md
+        * Fixed bad formatting and context.
+        * Fixed typos in code comments.
+        * Fixed several typos in docs.
+
+??? question "Pull Requests"
+    * PR #29
+    * PR #32
+
+&nbsp; 
+
+&nbsp; 
+
+## v0.2.3 (2022-08-11)
 
 ??? new "New Features"
     - [x] **Docs:**
-        * Added Zenodo Bibtex entry and badge in docs for easily citing a DeFFcode release.
+        * Added Zenodo Bibtex entry and badge in docs for easy citation.
         * Added new `<div>` tag bounding-box style to the Static FFmpeg binary download links in FFmpeg Installation Doc for better accessibility.
     - [x] **Maintenance:** 
         * Switched to new Issue GitHub's form schema using YAML:
diff --git a/docs/contribution/issue.md b/docs/contribution/issue.md
index 9dcd143..5603347 100644
--- a/docs/contribution/issue.md
+++ b/docs/contribution/issue.md
@@ -52,6 +52,6 @@ If you've found a new bug or you've come up with some new feature which can impr
 * Add a brief but descriptive title for your issue.
 * Keep the issue phrasing in context of the problem.
 * Attach source-code/screenshots if you have one.
-* Finally, raise it by choosing the appropriate Issue Template: [Bug report](https://github.com/abhiTronix/deffcode/issues/new?labels=issue%3A+bug&template=bug_report.md), [Proposal](https://github.com/abhiTronix/deffcode/issues/new?labels=issue%3A+proposal&template=proposal.md), [Question](https://github.com/abhiTronix/deffcode/issues/new?labels=issue%3A+question&template=question.md).
+* Finally, raise it by choosing the appropriate Issue Template: [**Bug report 🐞**](https://github.com/abhiTronix/deffcode/issues/new?assignees=abhiTronix&labels=Bug+%3Alady_beetle%3A%2CNeeds+Triage+%3Amonocle_face%3A&template=bug_report.yaml&title=%5BBug%5D%3A+), [Idea 💡](https://github.com/abhiTronix/deffcode/issues/new?assignees=&labels=Idea+%3Abulb%3A&template=idea.yaml&title=%5BIdea%5D%3A+), [Question ❔](https://github.com/abhiTronix/deffcode/issues/new?assignees=&labels=Question+%3Agrey_question%3A&template=question.yaml&title=%5BQuestion%5D%3A+).
 
 &nbsp; 
\ No newline at end of file
diff --git a/docs/index.md b/docs/index.md
index 0f0d44e..972b98c 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -31,7 +31,7 @@ limitations under the License.
 
 **==Highly Flexible== -** DeFFcode APIs gains an edge over other Wrappers by providing **complete control over the underline pipeline** including **access to almost any FFmpeg specification thinkable** such as specifying framerate, resolution, hardware decoder(s), filtergraph(s), and pixel-format(s) that are readily **supported by all well known Computer Vision libraries**.
 
-**==Highly Convenient== -**  FFmpeg has a steep learning curve especially for users unfamiliar with a command line interface. DeFFcode helps users by keeping the **same [OpenCV-Python](https://docs.opencv.org/4.x/d6/d00/tutorial_py_root.html) _(Python API for OpenCV)_ coding syntax for its APIs**, thereby making it even **easier to learn, create, and develop FFmpeg based apps** in Python.
+**==Highly Convenient== -**  FFmpeg has a steep learning curve especially for users unfamiliar with a command line interface. DeFFcode helps users by providing similar to OpenCV, [**Index based Camera Device Capturing**](recipes/basic/decode-camera-devices) and the **same [OpenCV-Python](https://docs.opencv.org/4.x/d6/d00/tutorial_py_root.html) _(Python API for OpenCV)_ coding syntax for its APIs**, thereby making it even **easier to learn, create, and develop FFmpeg based apps** in Python.
 
 &thinsp;
 
@@ -43,6 +43,7 @@ Here are some key features that stand out:
 - [x] Flexible API with access to almost any FFmpeg specification thinkable.
 - [x] Supports a wide-range of media streams/devices/protocols as input source. 
 - [x] Curated list of well-documented recipes ranging from [**Basic**](recipes/basic/) to [**Advanced**](recipes/advanced/) skill levels.
+- [x] Hands down the easiest [**Index based Camera Device Capturing**](recipes/basic/decode-camera-devices), similar to OpenCV.
 - [x] Memory efficient **Live [Simple](recipes/basic/transcode-live-frames-simplegraphs/#transcoding-live-simple-filtergraphs) & [Complex](recipes/advanced/transcode-live-frames-complexgraphs/#transcoding-live-complex-filtergraphs) Filtergraphs**. _(Yes, You read it correctly "Live"!)_
 - [x] Lightning fast dedicated **:fontawesome-solid-microchip: GPU-Accelerated Video [Decoding](recipes/advanced/decode-hw-acceleration/#hardware-accelerated-video-decoding) & [Transcoding](recipes/advanced/transcode-hw-acceleration/#hardware-accelerated-video-transcoding)**.
 - [x] Enables precise FFmpeg [**Frame Seeking**](recipes/basic/save-keyframe-image/#extracting-key-frames-as-png-image) with pinpoint accuracy.
@@ -196,18 +197,18 @@ It is something I am doing with my own free time. But so much more needs to be d
 
 Here is a Bibtex entry you can use to cite this project in a publication:
 
-[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6976948.svg)](https://doi.org/10.5281/zenodo.6976948)
+[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6984364.svg)](https://doi.org/10.5281/zenodo.6984364)
 
 ```BibTeX
 @software{deffcode,
   author       = {Abhishek Thakur},
-  title        = {abhiTronix/deffcode: v0.2.2},
+  title        = {abhiTronix/deffcode: v0.2.3},
   month        = aug,
   year         = 2022,
   publisher    = {Zenodo},
-  version      = {v0.2.2},
-  doi          = {10.5281/zenodo.6976948},
-  url          = {https://doi.org/10.5281/zenodo.6976948}
+  version      = {v0.2.3},
+  doi          = {10.5281/zenodo.6984364},
+  url          = {https://doi.org/10.5281/zenodo.6984364}
 }
 ```
 
diff --git a/docs/overrides/main.html b/docs/overrides/main.html
index 6d3a406..904dac6 100644
--- a/docs/overrides/main.html
+++ b/docs/overrides/main.html
@@ -24,9 +24,9 @@
 {% endblock %}
 {% block announce %}
   <!-- Add announcement here, including arbitrary HTML -->
-  {% set announcement_link = config.site_url ~ '/recipes/basic/decode-live-feed-devices/' %}
+  {% set announcement_link = config.site_url ~ '/recipes/basic/decode-camera-devices/#decoding-camera-devices-using-indexes' %}
 
-  <b>Hey, Live Feed Devices support has been added in <code>v0.2.2</code>. Checkout these <a href="{{ announcement_link }}">new recipes <span class="twemoji"> {% include ".icons/material/pot-steam-outline.svg" %} </span> ➶</a></b>
+  <b>Hey, Index based Camera Device Capture support has been added in <code>v0.2.4</code>. Checkout these <a href="{{ announcement_link }}">new recipes <span class="twemoji"> {% include ".icons/material/pot-steam-outline.svg" %} </span> ➶</a></b>
 {% endblock %}
 {% block outdated %}
   You're not viewing the latest version.
diff --git a/docs/recipes/advanced/decode-hw-acceleration.md b/docs/recipes/advanced/decode-hw-acceleration.md
index d2e0c56..e38c62f 100644
--- a/docs/recipes/advanced/decode-hw-acceleration.md
+++ b/docs/recipes/advanced/decode-hw-acceleration.md
@@ -22,7 +22,7 @@ limitations under the License.
 
 !!! abstract "FFmpeg offer access to dedicated GPU hardware with varying support on different platforms for performing a range of video-related tasks to be completed faster or using less of other resources (particularly CPU)."
 
-> By default, DeFFcode's FFdecoder API uses the Input Source's video-decoder _(extracted using Sourcer API)_ itself for decoding its input. However, you could easily change the video-decoder to your desired specific **supported Video-Decoder** using the `-vcodec` FFmpeg option by way of its [`ffparams`](../../reference/ffdecoder/params/#ffparams) dictionary parameter. This means easy access to GPU Accelerated Hardware Decoder to get better playback and accelerated video decoding on GPUs that will generate equivalent output to software decoders, but may use less power and CPU to do so.
+> By default, DeFFcode's FFdecoder API uses the Input Source's video-decoder _(extracted using Sourcer API)_ itself for decoding its input. However, you could easily change the video-decoder to your desired specific **supported Video-Decoder** using FFmpeg options by way of its [`ffparams`](../../reference/ffdecoder/params/#ffparams) dictionary parameter. This means easy access to GPU Accelerated Hardware Decoder to get better playback and accelerated video decoding on GPUs that will generate equivalent output to software decoders, but may use less power and CPU to do so.
 
 !!! tip "Use `#!sh ffmpeg -decoders` terminal command to lists all FFmpeg supported decoders."
 
@@ -34,27 +34,6 @@ We'll discuss its Hardware-Accelerated Video Decoding capabilities briefly in th
 
     ==DeFFcode APIs **MUST** requires valid FFmpeg executable for all of its core functionality==, and any failure in detection will raise `RuntimeError` immediately. Follow dedicated [FFmpeg Installation doc ➶](../../../installation/ffmpeg_install/) for its installation.
 
-???+ info "Additional Python Dependencies for following recipes"
-
-    Following recipes requires additional python dependencies which can be installed easily as below:
-
-    - [x] **OpenCV:** OpenCV is required for previewing video frames. You can easily install it directly via [`pip`](https://pypi.org/project/opencv-python/):
-
-        ??? tip "OpenCV installation from source"
-
-            You can also follow online tutorials for building & installing OpenCV on [Windows](https://www.learnopencv.com/install-opencv3-on-windows/), [Linux](https://www.pyimagesearch.com/2018/05/28/ubuntu-18-04-how-to-install-opencv/), [MacOS](https://www.pyimagesearch.com/2018/08/17/install-opencv-4-on-macos/) and [Raspberry Pi](https://www.pyimagesearch.com/2018/09/26/install-opencv-4-on-your-raspberry-pi/) machines manually from its source. 
-
-            :warning: Make sure not to install both *pip* and *source* version together. Otherwise installation will fail to work!
-
-        ??? info "Other OpenCV binaries"
-
-            OpenCV mainainers also provide additional binaries via pip that contains both main modules and contrib/extra modules [`opencv-contrib-python`](https://pypi.org/project/opencv-contrib-python/), and for server (headless) environments like [`opencv-python-headless`](https://pypi.org/project/opencv-python-headless/) and [`opencv-contrib-python-headless`](https://pypi.org/project/opencv-contrib-python-headless/). You can also install ==any one of them== in similar manner. More information can be found [here](https://github.com/opencv/opencv-python#installation-and-usage).
-
-
-        ```sh
-        pip install opencv-python       
-        ```
-
 
 !!! note "Always use FFdecoder API's [`terminate()`](../../reference/ffdecoder/#deffcode.ffdecoder.FFdecoder.terminate) method at the end to avoid undesired behavior."
 
@@ -77,50 +56,69 @@ We'll discuss its Hardware-Accelerated Video Decoding capabilities briefly in th
     These assumptions **MAY/MAY NOT** suit your current setup. Kindly use suitable parameters based your system platform and hardware settings only.
 
 
-In this example, we will be using Nvidia's **H.264 CUVID Video-decoder(`h264_cuvid`)** in FFdecoder API to achieve fully-accelerated hardware video decoding of **BGR24** frames from a given Video file _(say `foo.mp4`)_ on :fontawesome-brands-windows: Windows Machine, and preview them using OpenCV Library's `cv2.imshow()` method.
+In this example, we will be using Nvidia's Hardware Accerlated **CUDA Video-decoder(`cuda`)** in FFdecoder API to automatically detect NV-accelerated video codec and achieve GPU-accelerated hardware video decoding of **YUV420p** frames from a given Video file _(say `foo.mp4`)_ on :fontawesome-brands-windows: Windows Machine.
 
 !!! info "More information on Nvidia's CUVID can be found [here ➶](https://developer.nvidia.com/blog/nvidia-ffmpeg-transcoding-guide/)"
 
-???+ warning "Remember to check H.264 CUVID Video-decoder support in FFmpeg"
-
-    To use `h264_cuvid` decoder, remember to check if your FFmpeg compiled with H.264 CUVID decoder support. You can easily do this by executing following one-liner command in your terminal, and observing if output contains something similar as follows:
-
-    ```sh
-    $ ffmpeg  -hide_banner -decoders | grep h264 
-
-    VFS..D h264                 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
-    V....D h264_qsv             H264 video (Intel Quick Sync Video acceleration) (codec h264)
-    V..... h264_cuvid           Nvidia CUVID H264 decoder (codec h264)
-    ```
-
-    !!! tip "You can also use optimized HEVC CUVID Video-decoder(`hevc_cuvid`) in the similar way, if supported."
-
+!!! warning "YUV video-frames decoded with DeFFcode APIs are not yet supported by OpenCV methods."
+    Currently, there's no way to use DeFFcode APIs decoded YUV video-frames in OpenCV methods, and also you cannot change pixel format to any other due to NV-accelerated video codec supporting only few pixel-formats.
 
 !!! note "To learn about exclusive `-ffprefixes` parameter. See [Exclusive Parameters ➶](../../reference/ffdecoder/params/#b-exclusive-parameters)"
 
 ```python
 # import the necessary packages
 from deffcode import FFdecoder
-import cv2
+import json
 
 # define suitable FFmpeg parameter
 ffparams = {
-    "-vcodec": "h264_cuvid", # CUVID H.264 Video-decoder
-    "-ffprefixes": ["-vsync", "0"],
+    "-vcodec": None,  # skip any decoder and let FFmpeg chose
+    "-ffprefixes": [
+        "-vsync",
+        "0",
+        "-hwaccel", # chooses appropriate HW accelerator
+        "cuda",
+        "-hwaccel_output_format", # keeps the decoded frames in GPU memory
+        "cuda",
+    ],
+    "-custom_resolution": "null",  # discard `-custom_resolution`
+    "-framerate": "null",  # discard `-framerate`
+    "-vf": "scale_npp=format=yuv420p,hwdownload,format=yuv420p,fps=30.0",  # define your filters
 }
 
-# initialize and formulate the decoder with suitable source and params
+# initialize and formulate the decoder with params and custom filters
 decoder = FFdecoder(
-    "foo.mp4", frame_format="bgr24", verbose=True, **ffparams
+    "foo.mp4", frame_format="null", verbose=True, **ffparams  # discard frame_format
 ).formulate()
 
-# grab the RGB24(default) frame from the decoder
+# grab the YUV420 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}
+
+# terminate the decoder
+decoder.terminate()
+```
+<!--#TODO
+???+ danger "Remember to check H.264 CUVID Video-decoder support in FFmpeg"
+
+    To use `h264_cuvid` decoder, remember to check if your FFmpeg compiled with H.264 CUVID decoder support. You can easily do this by executing following one-liner command in your terminal, and observing if output contains something similar as follows:
+
+    ```sh
+    $ ffmpeg  -hide_banner -decoders | grep h264 
+
+    VFS..D h264                 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
+    V....D h264_qsv             H264 video (Intel Quick Sync Video acceleration) (codec h264)
+    V..... h264_cuvid           Nvidia CUVID H264 decoder (codec h264)
+    ```
+
+    !!! tip "You can also use optimized HEVC CUVID Video-decoder(`hevc_cuvid`) in the similar way, if supported."
+-->
+<!--#TODO
     # Show output window
     cv2.imshow("Output", frame)
 
@@ -128,11 +126,7 @@ for frame in decoder.generateFrame():
     key = cv2.waitKey(1) & 0xFF
     if key == ord("q"):
         break
+-->
 
-# close output window
-cv2.destroyAllWindows()
-# terminate the decoder
-decoder.terminate()
-```
 
 &nbsp;
\ No newline at end of file
diff --git a/docs/recipes/basic/decode-live-feed-devices.md b/docs/recipes/advanced/decode-live-feed-devices.md
similarity index 98%
rename from docs/recipes/basic/decode-live-feed-devices.md
rename to docs/recipes/advanced/decode-live-feed-devices.md
index b81eaa3..196c3b5 100644
--- a/docs/recipes/basic/decode-live-feed-devices.md
+++ b/docs/recipes/advanced/decode-live-feed-devices.md
@@ -18,9 +18,9 @@ limitations under the License.
 ======================================================================
 -->
 
-# :material-webcam: Decoding Live Feed Devices
+# :material-camera-iris: Decoding Live Feed Devices
 
-> DeFFcode's FFdecoder API provide effortless support for Live Feed Devices using two parameters: [`source`](../../reference/sourcer/params/#source) parameter which accepts device name or its path, and [`source_demuxer`](../../reference/sourcer/params/#source_demuxer) parameter to specify demuxer for the given input device. 
+> DeFFcode's FFdecoder API provide effortless support for any Live Feed Devices using two parameters: [`source`](../../reference/sourcer/params/#source) parameter which accepts device name or its path, and [`source_demuxer`](../../reference/sourcer/params/#source_demuxer) parameter to specify demuxer for the given input device. 
 
 We'll discuss the Live Feed Devices support using both these parameters briefly in the following recipes:
 
@@ -60,7 +60,7 @@ We'll discuss the Live Feed Devices support using both these parameters briefly
 
 &thinsp;
 
-## Capturing and Previewing frames from a Webcam
+## Capturing and Previewing frames from a Webcam using Custom Demuxer
 
 ???+ alert "Example Assumptions"
 
diff --git a/docs/recipes/advanced/index.md b/docs/recipes/advanced/index.md
index 421c168..b97c3b8 100644
--- a/docs/recipes/advanced/index.md
+++ b/docs/recipes/advanced/index.md
@@ -45,13 +45,15 @@ The following challenging recipes will take your skills to the next level and wi
 &thinsp;
 
 ## Advanced :material-movie-play: Decoding Recipes
-
 - [x] **[:material-file-hidden: Decoding Live Virtual Sources](../advanced/decode-live-virtual-sources/#decoding-live-virtual-sources)**
     - [Generate and Decode frames from Sierpinski pattern](../advanced/decode-live-virtual-sources/#generate-and-decode-frames-from-sierpinski-pattern)
     - [Generate and Decode frames from Test Source pattern](../advanced/decode-live-virtual-sources/#generate-and-decode-frames-from-test-source-pattern)
     - [Generate and Decode frames from Gradients with custom Text effect](../advanced/decode-live-virtual-sources/#generate-and-decode-frames-from-gradients-with-custom-text-effect)
     - [Generate and Decode frames from Mandelbrot test pattern with vectorscope & waveforms](../advanced/decode-live-virtual-sources/#generate-and-decode-frames-from-mandelbrot-test-pattern-with-vectorscope-waveforms)
     - [Generate and Decode frames from Game of Life Visualization](../advanced/decode-live-virtual-sources/#generate-and-decode-frames-from-game-of-life-visualization)
+- [x] **[:material-camera-iris: Decoding Live Feed Devices](../advanced/decode-live-feed-devices)**
+    - [Capturing and Previewing frames from a Webcam using Custom Demuxer](../advanced/decode-live-feed-devices/#capturing-and-previewing-frames-from-a-webcam-using-custom-demuxer)
+    - [Capturing and Previewing frames from your Desktop](../advanced/decode-live-feed-devices/#capturing-and-previewing-frames-from-your-desktop) _(Screen Recording)_
 - [x] **[:octicons-cpu-16: Hardware-Accelerated Video Decoding](../advanced/decode-hw-acceleration/#hardware-accelerated-video-decoding)**
     - [GPU-accelerated Hardware-based Video Decoding](../advanced/decode-hw-acceleration/#gpu-accelerated-hardware-based-video-decoding)
 
diff --git a/docs/recipes/advanced/transcode-art-filtergraphs.md b/docs/recipes/advanced/transcode-art-filtergraphs.md
index c4b1420..e30c5e0 100644
--- a/docs/recipes/advanced/transcode-art-filtergraphs.md
+++ b/docs/recipes/advanced/transcode-art-filtergraphs.md
@@ -121,7 +121,7 @@ decoder = FFdecoder("foo.mp4", frame_format="bgr24", verbose=True, **ffparams).f
 # retrieve framerate from source JSON Metadata and pass it as `-input_framerate`
 # parameter for controlled framerate and define other parameters
 output_params = {
-    "-input_framerate": json.loads(decoder.metadata)["source_video_framerate"],
+    "-input_framerate": json.loads(decoder.metadata)["output_framerate"],
 }
 
 # Define writer with default parameters and suitable
@@ -198,7 +198,7 @@ decoder = FFdecoder(
 # retrieve framerate from source JSON Metadata and pass it as `-input_framerate`
 # parameter for controlled framerate and define other parameters
 output_params = {
-    "-input_framerate": json.loads(decoder.metadata)["source_video_framerate"],
+    "-input_framerate": json.loads(decoder.metadata)["output_framerate"],
 }
 
 # Define writer with default parameters and suitable
@@ -266,7 +266,7 @@ decoder = FFdecoder(
 # retrieve framerate from source JSON Metadata and pass it as `-input_framerate`
 # parameter for controlled framerate and define other parameters
 output_params = {
-    "-input_framerate": json.loads(decoder.metadata)["source_video_framerate"],
+    "-input_framerate": json.loads(decoder.metadata)["output_framerate"],
 }
 
 # Define writer with default parameters and suitable
@@ -334,7 +334,7 @@ decoder = FFdecoder(
 # retrieve framerate from source JSON Metadata and pass it as `-input_framerate`
 # parameter for controlled framerate and define other parameters
 output_params = {
-    "-input_framerate": json.loads(decoder.metadata)["source_video_framerate"],
+    "-input_framerate": json.loads(decoder.metadata)["output_framerate"],
 }
 
 # Define writer with default parameters and suitable
diff --git a/docs/recipes/advanced/transcode-hw-acceleration.md b/docs/recipes/advanced/transcode-hw-acceleration.md
index 4eddb4a..7a3f0df 100644
--- a/docs/recipes/advanced/transcode-hw-acceleration.md
+++ b/docs/recipes/advanced/transcode-hw-acceleration.md
@@ -46,23 +46,6 @@ We'll discuss its Hardware-Accelerated Video Transcoding capabilities using thes
 
     Following recipes requires additional python dependencies which can be installed easily as below:
 
-    - [x] **OpenCV:** OpenCV is required for previewing and encoding video frames. You can easily install it directly via [`pip`](https://pypi.org/project/opencv-python/):
-
-        ??? tip "OpenCV installation from source"
-
-            You can also follow online tutorials for building & installing OpenCV on [Windows](https://www.learnopencv.com/install-opencv3-on-windows/), [Linux](https://www.pyimagesearch.com/2018/05/28/ubuntu-18-04-how-to-install-opencv/), [MacOS](https://www.pyimagesearch.com/2018/08/17/install-opencv-4-on-macos/) and [Raspberry Pi](https://www.pyimagesearch.com/2018/09/26/install-opencv-4-on-your-raspberry-pi/) machines manually from its source. 
-
-            :warning: Make sure not to install both *pip* and *source* version together. Otherwise installation will fail to work!
-
-        ??? info "Other OpenCV binaries"
-
-            OpenCV mainainers also provide additional binaries via pip that contains both main modules and contrib/extra modules [`opencv-contrib-python`](https://pypi.org/project/opencv-contrib-python/), and for server (headless) environments like [`opencv-python-headless`](https://pypi.org/project/opencv-python-headless/) and [`opencv-contrib-python-headless`](https://pypi.org/project/opencv-contrib-python-headless/). You can also install ==any one of them== in similar manner. More information can be found [here](https://github.com/opencv/opencv-python#installation-and-usage).
-
-
-        ```sh
-        pip install opencv-python       
-        ```
-
     - [x] **VidGear:** VidGear is required for lossless encoding of video frames into file/stream. You can easily install it directly via [`pip`](https://pypi.org/project/opencv-python/):
 
         ```sh
@@ -108,21 +91,9 @@ We'll discuss its Hardware-Accelerated Video Transcoding capabilities using thes
 
     !!! summary "On the whole, You don't have to worry about it as you're getting to manipulate the real-time video frames with immense speed and flexibility which is impossible to do otherwise."
 
-In this example, we will be using Nvidia's **H.264 CUVID Video-decoder(`h264_cuvid`) with `–hwaccel cuvid` accelerator** in FFdecoder API to decode and keep decoded **BGR24** frames from a given Video file _(say `foo.mp4`)_ within GPU, all while rescaling _(with nvcuvid's `resize`)_ as well as encoding them in real-time with WriteGear API using Nvidia's hardware accelerated **H.264 NVENC Video-encoder(`h264_nvenc`)** into lossless video file within GPU. 
-
-??? warning "Remember to check H.264 CUVID decoder and H.264 NVENC encoder support in FFmpeg"
+In this example, we will be using Nvidia's Hardware Accerlated **CUDA Video-decoder(`cuda`)** in FFdecoder API to decode and keep decoded **YUV420p** frames from a given Video file _(say `foo.mp4`)_ within GPU, all while rescaling _(with nvcuvid's `resize`)_ as well as encoding them in real-time with WriteGear API using Nvidia's hardware accelerated **H.264 NVENC Video-encoder(`h264_nvenc`)** into lossless video file within GPU. 
 
-    - [x] **Using `h264_cuvid` decoder**: Remember to check if your FFmpeg compiled with H.264 CUVID decoder support. You can easily do this by executing following one-liner command in your terminal, and observing if output contains something similar as follows:
-
-        ```sh
-        $ ffmpeg  -hide_banner -decoders | grep h264 
-
-        VFS..D h264                 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
-        V....D h264_qsv             H264 video (Intel Quick Sync Video acceleration) (codec h264)
-        V..... h264_cuvid           Nvidia CUVID H264 decoder (codec h264)
-        ```
-
-        !!! note "You can also use optimized HEVC CUVID decoder(`hevc_cuvid`) in the similar way, if supported."
+??? note "Remember to check H.264 NVENC encoder support in FFmpeg"
 
     - [x] **Using `h264_nvenc` encoder**: Remember to check if your FFmpeg compiled with H.264 NVENC encoder support. You can easily do this by executing following one-liner command in your terminal, and observing if output contains something similar as follows:
 
@@ -143,6 +114,10 @@ In this example, we will be using Nvidia's **H.264 CUVID Video-decoder(`h264_cuv
 !!! tip "You can use FFdecoder's [`metadata`](../../reference/ffdecoder/#deffcode.ffdecoder.FFdecoder.metadata) property object that dumps source Video's metadata information _(as JSON string)_ to retrieve source framerate."
 
 
+!!! warning "YUV video-frames decoded with DeFFcode APIs are not yet supported by OpenCV methods."
+    Currently, there's no way to use DeFFcode APIs decoded YUV video-frames in OpenCV methods, and also you cannot change pixel format to any other due to NV-accelerated video codec supporting only few pixel-formats.
+
+
 ```python
 # import the necessary packages
 from deffcode import FFdecoder
@@ -151,28 +126,39 @@ import json
 
 # define suitable FFmpeg parameter
 ffparams = {
-    "-vcodec": "h264_cuvid",  # H.264 CUVID decoder
-    "-ffprefixes": ["-vsync", "0", "–hwaccel", "cuvid"],  # accelerator
+    "-vcodec": None,  # skip any decoder and let FFmpeg chose
+    "-ffprefixes": [
+        "-vsync",
+        "0",
+        "-hwaccel", # chooses appropriate HW accelerator
+        "cuda",
+        "-hwaccel_output_format", # keeps the decoded frames in GPU memory
+        "cuda",
+    ],
+    "-custom_resolution": "null",  # discard `-custom_resolution`
+    "-framerate": "null",  # discard `-framerate`
+    "-vf": "scale_npp=format=yuv420p,hwdownload,format=yuv420p,fps=30.0",  # define your filters
 }
 
-# initialize and formulate the decoder with suitable source and params
+# initialize and formulate the decoder with params and custom filters
 decoder = FFdecoder(
-    "foo.mp4", frame_format="bgr24", verbose=True, **ffparams
+    "foo.mp4", frame_format="null", verbose=True, **ffparams  # discard frame_format
 ).formulate()
 
-# retrieve framerate from source JSON Metadata and pass it as `-input_framerate`
-# parameter for controlled framerate and define other parameters
+# retrieve framerate from JSON Metadata and pass it as 
+# `-input_framerate` parameter for controlled framerate
+# and add input pixfmt as yuv420p also
 output_params = {
-    "-input_framerate": json.loads(decoder.metadata)["source_video_framerate"],
-    "-vcodec": "h264_nvenc",  # H.264 NVENC encoder
-    "–resize": "1280x720",  # rescale to 1280x720
+    "-input_framerate": json.loads(decoder.metadata)["output_framerate"],
+    "-vcodec": "h264_nvenc",
+    "-input_pixfmt": "yuv420p"
 }
 
-# Define writer with defined parameters and suitable
-# output filename for e.g. `output_foo.mp4`
-writer = WriteGear(output_filename="output_foo.mp4", **output_params)
+# Define writer with default parameters and suitable
+# output filename for e.g. `output_foo_yuv.mp4`
+writer = WriteGear(output_filename="output_foo_yuv.mp4", **output_params)
 
-# grab the BGR24 frame from the decoder
+# grab the YUV420 frame from the decoder
 for frame in decoder.generateFrame():
 
     # check if frame is None
@@ -181,7 +167,7 @@ for frame in decoder.generateFrame():
 
     # {do something with the frame here}
 
-    # writing BGR24 frame to writer
+    # writing YUV420 frame to writer
     writer.write(frame)
 
 # terminate the decoder
diff --git a/docs/recipes/advanced/transcode-live-frames-complexgraphs.md b/docs/recipes/advanced/transcode-live-frames-complexgraphs.md
index d6c989e..53abc4c 100644
--- a/docs/recipes/advanced/transcode-live-frames-complexgraphs.md
+++ b/docs/recipes/advanced/transcode-live-frames-complexgraphs.md
@@ -122,7 +122,7 @@ decoder = FFdecoder(
 # retrieve framerate from source JSON Metadata and pass it as `-input_framerate`
 # parameter for controlled framerate and define other parameters
 output_params = {
-    "-input_framerate": json.loads(decoder.metadata)["source_video_framerate"],
+    "-input_framerate": json.loads(decoder.metadata)["output_framerate"],
 }
 
 # Define writer with default parameters and suitable
diff --git a/docs/recipes/basic/decode-camera-devices.md b/docs/recipes/basic/decode-camera-devices.md
new file mode 100644
index 0000000..c43accc
--- /dev/null
+++ b/docs/recipes/basic/decode-camera-devices.md
@@ -0,0 +1,199 @@
+<!--
+======================================================================
+DeFFcode library source-code is deployed under the Apache 2.0 License:
+
+Copyright (c) 2021 Abhishek Thakur(@abhiTronix) <abhi.una12@gmail.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+======================================================================
+-->
+
+# :material-webcam: Decoding Camera Devices using Indexes
+
+> With DeFFcode APIs, we are able to probe and enumerate all Camera Devices names along with their respective "device indexes" or "camera indexes" no matter how many cameras are connected to your system. This makes Camera Devices decoding as simple as [**OpenCV**](https://opencv.org/), where one can effortlessly access a specific Camera Device just by the specifying the matching index of it. These indexes are much easier to read, memorize, and type, and one don't have to remember long Device names or worry about its Demuxer. 
+
+We'll discuss the Decoding Camera Devices using Indexes briefly in the following recipes:
+
+&thinsp;
+
+!!! warning "DeFFcode APIs requires FFmpeg executable"
+
+    ==DeFFcode APIs **MUST** requires valid FFmpeg executable for all of its core functionality==, and any failure in detection will raise `RuntimeError` immediately. Follow dedicated [FFmpeg Installation doc ➶](../../../installation/ffmpeg_install/) for its installation.
+
+???+ info "Additional Python Dependencies for following recipes"
+
+    Following recipes requires additional python dependencies which can be installed easily as below:
+
+    - [x] **OpenCV:** OpenCV is required for previewing video frames. You can easily install it directly via [`pip`](https://pypi.org/project/opencv-python/):
+
+        ??? tip "OpenCV installation from source"
+
+            You can also follow online tutorials for building & installing OpenCV on [Windows](https://www.learnopencv.com/install-opencv3-on-windows/), [Linux](https://www.pyimagesearch.com/2018/05/28/ubuntu-18-04-how-to-install-opencv/), [MacOS](https://www.pyimagesearch.com/2018/08/17/install-opencv-4-on-macos/) and [Raspberry Pi](https://www.pyimagesearch.com/2018/09/26/install-opencv-4-on-your-raspberry-pi/) machines manually from its source. 
+
+            :warning: Make sure not to install both *pip* and *source* version together. Otherwise installation will fail to work!
+
+        ??? info "Other OpenCV binaries"
+
+            OpenCV mainainers also provide additional binaries via pip that contains both main modules and contrib/extra modules [`opencv-contrib-python`](https://pypi.org/project/opencv-contrib-python/), and for server (headless) environments like [`opencv-python-headless`](https://pypi.org/project/opencv-python-headless/) and [`opencv-contrib-python-headless`](https://pypi.org/project/opencv-contrib-python-headless/). You can also install ==any one of them== in similar manner. More information can be found [here](https://github.com/opencv/opencv-python#installation-and-usage).
+
+
+        ```sh
+        pip install opencv-python       
+        ```
+
+
+!!! note "Always use FFdecoder API's [`terminate()`](../../reference/ffdecoder/#deffcode.ffdecoder.FFdecoder.terminate) method at the end to avoid undesired behavior."
+
+??? danger "Never name your python script `deffcode.py`"
+
+    When trying out these recipes, never name your python script `deffcode.py` otherwise it will result in `ModuleNotFound` error.
+
+&thinsp;
+
+## Enumerating all Camera Devices with Indexes
+
+> In Sourcer API, you can easily use its [`enumerate_devices`](../../../reference/sourcer/#deffcode.sourcer.Sourcer.enumerate_devices) property object to enumerate all probed Camera Devices _(connected to your system)_ as **dictionary object** with device indexes as keys and device names as their respective values. 
+
+??? danger "Requirement for Enumerating all Camera Devices in Sourcer API"
+
+    - [x] **MUST have appropriate FFmpeg binaries, Drivers, and Softwares installed:**
+        
+        Internally, DeFFcode APIs achieves Index based Camera Device Capturing by employing some specific FFmpeg demuxers on different platforms(OSes). These platform specific demuxers are as follows:
+
+        | Platform(OS) | Demuxer |
+        |:------------:|:-------|
+        | :fontawesome-brands-windows: Windows OS|[`dshow`](https://trac.ffmpeg.org/wiki/DirectShow) _(or DirectShow)_ |
+        | :material-linux: Linux OS | [`video4linux2`](https://trac.ffmpeg.org/wiki/Capture/Webcam#Linux) _(or its alias `v4l2`)_ |
+        | :material-apple: Mac OS | [`avfoundation`](https://ffmpeg.org/ffmpeg-devices.html#avfoundation) |
+
+        **:warning: Important:** Kindly make sure your FFmpeg binaries support these platform specific demuxers as well as system have the appropriate video drivers and related softwares installed.
+
+    - [x] The [`source`](../../../reference/sourcer/params/#source) parameter value **MUST be any Camera Device index** that can be of either **integer** _(e.g. `-1`,`0`,`1`, etc.)_ or **string of integer** _(e.g. `"-1"`,`"0"`,`"1"`, etc.)_ type.
+
+    - [x] The [`source_demuxer`](../../../reference/sourcer/params/#source_demuxer) parameter value  **MUST be either `None`_(also means empty)_ or `"auto"`**. 
+
+In this example we will enumerate all probed Camera Devices connected on a :fontawesome-brands-windows: Windows machine using [`enumerate_devices`](../../../reference/sourcer/#deffcode.sourcer.Sourcer.enumerate_devices) property object in Sourcer API, both as dictionary object and JSON string.
+
+```python
+# import the necessary packages
+from deffcode import Sourcer
+import json
+
+# initialize and formulate the decoder
+sourcer = Sourcer("0").probe_stream()
+
+# enumerate probed devices as Dictionary object(`dict`)
+print(sourcer.enumerate_devices)
+
+# enumerate probed devices as JSON string(`json.dump`)
+print(json.dumps(sourcer.enumerate_devices,indent=2))
+```
+
+???+ abstract "After running above python code, the resultant Terminal Output will look something as following on :fontawesome-brands-windows:Windows machine:"
+
+    === "As Dictionary object"
+
+        ```python
+        {0: 'Integrated Camera', 1: 'USB2.0 Camera', 2: 'DroidCam Source'}
+        ```
+    
+    === "As JSON string"
+
+        ```json
+        {
+          "0": "Integrated Camera",
+          "1": "USB2.0 Camera",
+          "2": "DroidCam Source"
+        }
+        ```
+
+&nbsp;
+
+## Capturing and Previewing frames from a Camera using Indexes
+
+> After knowing the index of Camera Device with Sourcer API, One can easily Capture desired Camera Device in FFdecoder API by specifying its matching index value either as **integer** or **string of integer** type to its `source` parameter.
+
+??? danger "Requirement for Index based Camera Device Capturing in FFdecoder API"
+
+    - [x] **MUST have appropriate FFmpeg binaries, Drivers, and Softwares installed:**
+        
+        Internally, DeFFcode APIs achieves Index based Camera Device Capturing by employing some specific FFmpeg demuxers on different platforms(OSes). These platform specific demuxers are as follows:
+
+        | Platform(OS) | Demuxer |
+        |:------------:|:-------|
+        | :fontawesome-brands-windows: Windows OS|[`dshow`](https://trac.ffmpeg.org/wiki/DirectShow) _(or DirectShow)_ |
+        | :material-linux: Linux OS | [`video4linux2`](https://trac.ffmpeg.org/wiki/Capture/Webcam#Linux) _(or its alias `v4l2`)_ |
+        | :material-apple: Mac OS | [`avfoundation`](https://ffmpeg.org/ffmpeg-devices.html#avfoundation) |
+
+        **:warning: Important:** Kindly make sure your FFmpeg binaries support these platform specific demuxers as well as system have the appropriate video drivers and related softwares installed.
+    - [x] The [`source`](../../../reference/ffdecoder/params/#source) parameter value **MUST be exactly the probed Camera Device index** _(use Sourcer API's [`enumerate_devices`](../../../reference/sourcer/#deffcode.sourcer.Sourcer.enumerate_devices) to list them)_.
+    - [x] The [`source_demuxer`](../../../reference/ffdecoder/params/#source_demuxer) parameter value  **MUST be either `None`_(also means empty)_ or `"auto"`**. 
+
+In this example we will decode **BGR24** video frames from **Integrated Camera at index `0`** on a Windows Machine, and preview them using OpenCV Library's `cv2.imshow()` method.
+
+??? tip "Important Facts related to Camera Device Indexing"
+    - [x] **Camera Device indexes are 0-indexed**. So the first device is at `0`, second is at `1`, so on. So if the there are `n` devices, the last device is at `n-1`.
+    - [x] **Camera Device indexes can be of either integer** _(e.g. `0`,`1`, etc.)_ or **string of integer** _(e.g. `"0"`,`"1"`, etc.)_ **type**.
+    - [x] **Camera Device indexes can be negative** _(e.g. `-1`,`-2`, etc.)_, this means you can also start indexing from the end.
+        * For example, If there are three devices: 
+            ```python
+            {0: 'Integrated Camera', 1: 'USB2.0 Camera', 2: 'DroidCam Source'}
+            ```
+        * Then, You can specify Positive Indexes and its Equivalent Negative Indexes as follows:
+
+            | Positive Indexes | Equivalent Negative Indexes |
+            |:------------:|:-------:|
+            | `#!python FFdecoder("0").formulate()`| `#!python FFdecoder("-3").formulate()` |
+            | `#!python FFdecoder("1").formulate()`| `#!python FFdecoder("-2").formulate()` |
+            | `#!python FFdecoder("2").formulate()`| `#!python FFdecoder("-1").formulate()` |
+
+    !!! warning "Out of Index Camera Device index values will raise `ValueError` in FFdecoder API"
+
+```python
+# import the necessary packages
+from deffcode import FFdecoder
+import cv2
+
+# initialize and formulate the decoder with "0" index source for BGR24 output
+decoder = FFdecoder("0", frame_format="bgr24", verbose=True).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("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()
+```
+
+&nbsp;
+
+<!--
+External URLs
+-->
+[gitter]: https://gitter.im/deffcode-python/community
\ No newline at end of file
diff --git a/docs/recipes/basic/decode-image-sequences.md b/docs/recipes/basic/decode-image-sequences.md
index 1fa31e3..16ff2f9 100644
--- a/docs/recipes/basic/decode-image-sequences.md
+++ b/docs/recipes/basic/decode-image-sequences.md
@@ -186,7 +186,7 @@ In this example we will capture video frames from a Single Looping image using F
 from deffcode import FFdecoder
 import cv2
 
-# define `-loop 1` for looping
+# define `-loop 1` for infinite looping
 ffparams = {"-ffprefixes":["-loop", "1"]}
 
 # initialize and formulate the decoder with suitable source
diff --git a/docs/recipes/basic/decode-network-streams.md b/docs/recipes/basic/decode-network-streams.md
index 7a8c0e6..8f53d9e 100644
--- a/docs/recipes/basic/decode-network-streams.md
+++ b/docs/recipes/basic/decode-network-streams.md
@@ -104,7 +104,7 @@ decoder.terminate()
 
 In this example we will decode live **BGR24** video frames from RTSP/RTP protocol Streams in FFdecoder API, and preview them using OpenCV Library's `cv2.imshow()` method.
 
-!!! alert "This example assume you already have a RSTP Server running at specified RSTP address with syntax `rtsp://[RTSP_ADDRESS]:[RTSP_PORT]/[RTSP_PATH]` with video data already being published to it."
+!!! alert "This example assume you already have a RSTP Server running at specified RSTP address with syntax `rtsp://[RTSP_ADDRESS]:[RTSP_PORT]/[RTSP_PATH]` and video data already being published to it."
 
 !!! tip "For creating your own RSTP Server locally and publishing video data to it, You can refer this [WriteGear API's bonus example ➶](https://abhitronix.github.io/vidgear/dev/help/writegear_ex/#using-writegears-compression-mode-for-rtsprtp-live-streaming)"
 
diff --git a/docs/recipes/basic/index.md b/docs/recipes/basic/index.md
index fa87895..b83f8a2 100644
--- a/docs/recipes/basic/index.md
+++ b/docs/recipes/basic/index.md
@@ -55,9 +55,9 @@ The following recipes should be reasonably accessible to beginners of any skill
     - [Accessing RGB frames from a video file](../basic/decode-video-files/#accessing-rgb-frames-from-a-video-file)
     - [Capturing and Previewing BGR frames from a video file](../basic/decode-video-files/#capturing-and-previewing-bgr-frames-from-a-video-file) _(OpenCV Support)_
     - [Playing with any other FFmpeg pixel formats](../basic/decode-video-files/#capturing-and-previewing-bgr-frames-from-a-video-file)
-- [x] **[:material-webcam: Decoding Live Feed Devices](../basic/decode-live-feed-devices/#decoding-live-feed-devices)**
-    - [Capturing and Previewing frames from a Webcam](../basic/decode-live-feed-devices/#capturing-and-previewing-frames-from-a-webcam)
-    - [Capturing and Previewing frames from your Desktop](../basic/decode-live-feed-devices/#capturing-and-previewing-frames-from-your-desktop) _(Screen Recording)_
+- [x] **[:material-webcam: Decoding Camera Devices using Indexes](../basic/decode-camera-devices)**
+    - [Enumerating all Camera Devices with Indexes](../basic/decode-camera-devices/#enumerating-all-camera-devices-with-indexes)
+    - [Capturing and Previewing frames from a Camera using Indexes](../basic/decode-camera-devices/#capturing-and-previewing-frames-from-a-camera-using-indexes)
 - [x] **[:fontawesome-solid-cloud-arrow-down: Decoding Network Streams](../basic/decode-network-streams/#decoding-network-streams)**
     - [Capturing and Previewing frames from a HTTPs Stream](../basic/decode-network-streams/#capturing-and-previewing-frames-from-a-https-stream)
     - [Capturing and Previewing frames from a RTSP/RTP Stream](../basic/decode-network-streams/#capturing-and-previewing-frames-from-a-rtsprtp-stream)
diff --git a/docs/recipes/basic/save-keyframe-image.md b/docs/recipes/basic/save-keyframe-image.md
index 911e4e7..ceb444f 100644
--- a/docs/recipes/basic/save-keyframe-image.md
+++ b/docs/recipes/basic/save-keyframe-image.md
@@ -86,8 +86,9 @@ In this example we will seek to `00:00:01.45`_(or 1045msec)_ in time and decode
 ??? tip "Time unit syntax in `-ss` FFmpeg parameter"
     
     You can use two different time unit formats with `-ss` FFmpeg parameter: 
-    - [x] **Sexagesimal(in seconds):** Uses *(HOURS:MM:SS.MILLISECONDS)*, such as in `01:23:45.678`
-    - [x] **Fractional:** such as in `02:30.05`, this is interpreted as 2 minutes, 30 seconds, and a half a second, which would be the same as using 150.5 in seconds.
+
+    - [x] **Sexagesimal(in seconds):** Uses *(HOURS:MM:SS.MILLISECONDS)* format, such as in `01:23:45.678`.
+    - [x] **Fractional:** such as in `02:30.05`. This is interpreted as _2 minutes, 30 and a half a second_, which would be the same as using `150.5` in seconds.
 
 === "Using Pillow"
 
diff --git a/docs/recipes/basic/transcode-live-frames-simplegraphs.md b/docs/recipes/basic/transcode-live-frames-simplegraphs.md
index 993240d..a0a2c19 100644
--- a/docs/recipes/basic/transcode-live-frames-simplegraphs.md
+++ b/docs/recipes/basic/transcode-live-frames-simplegraphs.md
@@ -85,7 +85,7 @@ In this example we will take the first 5 seconds of a video clip _(using [`trim`
 
 !!! info "OpenCV's `VideoWriter()` class requires a valid Output filename _(e.g. output_foo.avi)_, [FourCC](https://www.fourcc.org/fourcc.php) code, framerate, and resolution as input."
 
-!!! tip "You can use FFdecoder's [`metadata`](../../reference/ffdecoder/#deffcode.ffdecoder.FFdecoder.metadata) property object that dumps source Video's metadata information _(as JSON string)_ to retrieve source framerate and resolution."
+!!! tip "You can use FFdecoder's [`metadata`](../../reference/ffdecoder/#deffcode.ffdecoder.FFdecoder.metadata) property object that dumps source Video's metadata information _(as JSON string)_ to retrieve output framerate and resolution."
 
 !!! alert "By default, OpenCV expects `BGR` format frames in its `cv2.write()` method."
 
@@ -110,8 +110,8 @@ metadata_dict = json.loads(decoder.metadata)
 
 # prepare OpenCV parameters
 FOURCC = cv2.VideoWriter_fourcc("M", "J", "P", "G")
-FRAMERATE = metadata_dict["source_video_framerate"]
-FRAMESIZE = tuple(metadata_dict["source_video_resolution"])
+FRAMERATE = metadata_dict["output_framerate"]
+FRAMESIZE = tuple(metadata_dict["output_frames_resolution"])
 
 # Define writer with parameters and suitable output filename for e.g. `output_foo.avi`
 writer = cv2.VideoWriter("output_foo.avi", FOURCC, FRAMERATE, FRAMESIZE)
@@ -149,7 +149,7 @@ In this example we will crop real-time video frames by an area with size 2/3 of
 
 !!! info "OpenCV's `VideoWriter()` class requires a valid Output filename _(e.g. output_foo.avi)_, [FourCC](https://www.fourcc.org/fourcc.php) code, framerate, and resolution as input."
 
-!!! note "You can use FFdecoder's [`metadata`](../../reference/ffdecoder/#deffcode.ffdecoder.FFdecoder.metadata) property object that dumps source Video's metadata information _(as JSON string)_ to retrieve source framerate and resolution."
+!!! note "You can use FFdecoder's [`metadata`](../../reference/ffdecoder/#deffcode.ffdecoder.FFdecoder.metadata) property object that dumps source Video's metadata information _(as JSON string)_ to retrieve output framerate and resolution."
 
 !!! tip "More complex examples using `crop` filter can be found [here ➶](https://ffmpeg.org/ffmpeg-filters.html#toc-Examples-57) and can be applied similarly."
 
@@ -174,8 +174,8 @@ metadata_dict = json.loads(decoder.metadata)
 
 # prepare OpenCV parameters
 FOURCC = cv2.VideoWriter_fourcc("M", "J", "P", "G")
-FRAMERATE = metadata_dict["source_video_framerate"]
-FRAMESIZE = tuple(metadata_dict["source_video_resolution"])
+FRAMERATE = metadata_dict["output_framerate"]
+FRAMESIZE = tuple(metadata_dict["output_frames_resolution"])
 
 # Define writer with parameters and suitable output filename for e.g. `output_foo.avi`
 writer = cv2.VideoWriter("output_foo.avi", FOURCC, FRAMERATE, FRAMESIZE)
@@ -215,7 +215,7 @@ In this example we will rotate real-time video frames at an arbitrary angle by a
 
 !!! info "OpenCV's `VideoWriter()` class requires a valid Output filename _(e.g. output_foo.avi)_, [FourCC](https://www.fourcc.org/fourcc.php) code, framerate, and resolution as input."
 
-!!! note "You can use FFdecoder's [`metadata`](../../reference/ffdecoder/#deffcode.ffdecoder.FFdecoder.metadata) property object that dumps source Video's metadata information _(as JSON string)_ to retrieve source framerate and resolution."
+!!! note "You can use FFdecoder's [`metadata`](../../reference/ffdecoder/#deffcode.ffdecoder.FFdecoder.metadata) property object that dumps source Video's metadata information _(as JSON string)_ to retrieve output framerate and resolution."
 
 ```python
 # import the necessary packages
@@ -238,8 +238,8 @@ metadata_dict = json.loads(decoder.metadata)
 
 # prepare OpenCV parameters
 FOURCC = cv2.VideoWriter_fourcc("M", "J", "P", "G")
-FRAMERATE = metadata_dict["source_video_framerate"]
-FRAMESIZE = tuple(metadata_dict["source_video_resolution"])
+FRAMERATE = metadata_dict["output_framerate"]
+FRAMESIZE = tuple(metadata_dict["output_frames_resolution"])
 
 # Define writer with parameters and suitable output filename for e.g. `output_foo.avi`
 writer = cv2.VideoWriter("output_foo.avi", FOURCC, FRAMERATE, FRAMESIZE)
@@ -278,7 +278,7 @@ In this example we will rotate real-time video frames by 90 degrees counterclock
 
 !!! info "OpenCV's `VideoWriter()` class requires a valid Output filename _(e.g. output_foo.avi)_, [FourCC](https://www.fourcc.org/fourcc.php) code, framerate, and resolution as input."
 
-!!! note "You can use FFdecoder's [`metadata`](../../reference/ffdecoder/#deffcode.ffdecoder.FFdecoder.metadata) property object that dumps source Video's metadata information _(as JSON string)_ to retrieve source framerate and resolution."
+!!! note "You can use FFdecoder's [`metadata`](../../reference/ffdecoder/#deffcode.ffdecoder.FFdecoder.metadata) property object that dumps source Video's metadata information _(as JSON string)_ to retrieve output framerate and resolution."
 
 ```python
 # import the necessary packages
@@ -301,8 +301,8 @@ metadata_dict = json.loads(decoder.metadata)
 
 # prepare OpenCV parameters
 FOURCC = cv2.VideoWriter_fourcc("M", "J", "P", "G")
-FRAMERATE = metadata_dict["source_video_framerate"]
-FRAMESIZE = tuple(metadata_dict["source_video_resolution"])
+FRAMERATE = metadata_dict["output_framerate"]
+FRAMESIZE = tuple(metadata_dict["output_frames_resolution"])
 
 # Define writer with parameters and suitable output filename for e.g. `output_foo.avi`
 writer = cv2.VideoWriter("output_foo.avi", FOURCC, FRAMERATE, FRAMESIZE)
@@ -339,7 +339,7 @@ In this example we will horizontally flip and scale real-time video frames to ha
 
 !!! info "OpenCV's `VideoWriter()` class requires a valid Output filename _(e.g. output_foo.avi)_, [FourCC](https://www.fourcc.org/fourcc.php) code, framerate, and resolution as input."
 
-!!! note "You can use FFdecoder's [`metadata`](../../reference/ffdecoder/#deffcode.ffdecoder.FFdecoder.metadata) property object that dumps source Video's metadata information _(as JSON string)_ to retrieve source framerate and resolution."
+!!! note "You can use FFdecoder's [`metadata`](../../reference/ffdecoder/#deffcode.ffdecoder.FFdecoder.metadata) property object that dumps source Video's metadata information _(as JSON string)_ to retrieve output framerate and resolution."
 
 !!! tip "More complex examples using `scale` filter can be found [here ➶](https://ffmpeg.org/ffmpeg-filters.html#toc-Examples-107) and can be applied similarly."
 
@@ -364,8 +364,8 @@ metadata_dict = json.loads(decoder.metadata)
 
 # prepare OpenCV parameters
 FOURCC = cv2.VideoWriter_fourcc("M", "J", "P", "G")
-FRAMERATE = metadata_dict["source_video_framerate"]
-FRAMESIZE = tuple(metadata_dict["source_video_resolution"])
+FRAMERATE = metadata_dict["output_framerate"]
+FRAMESIZE = tuple(metadata_dict["output_frames_resolution"])
 
 # Define writer with parameters and suitable output filename for e.g. `output_foo.avi`
 writer = cv2.VideoWriter("output_foo.avi", FOURCC, FRAMERATE, FRAMESIZE)
diff --git a/docs/recipes/basic/transcode-live-frames.md b/docs/recipes/basic/transcode-live-frames.md
index 11f9cc7..7e873e2 100644
--- a/docs/recipes/basic/transcode-live-frames.md
+++ b/docs/recipes/basic/transcode-live-frames.md
@@ -87,10 +87,12 @@ In this example we will decode different pixel formats video frames from a given
 
 !!! info "OpenCV's `VideoWriter()` class requires a valid Output filename _(e.g. output_foo.avi)_, [FourCC](https://www.fourcc.org/fourcc.php) code, framerate, and resolution as input."
 
-!!! tip "You can use FFdecoder's [`metadata`](../../reference/ffdecoder/#deffcode.ffdecoder.FFdecoder.metadata) property object that dumps source Video's metadata information _(as JSON string)_ to retrieve source framerate and resolution."
+!!! tip "You can use FFdecoder's [`metadata`](../../reference/ffdecoder/#deffcode.ffdecoder.FFdecoder.metadata) property object that dumps source Video's metadata information _(as JSON string)_ to retrieve output framerate and resolution."
 
 !!! alert "By default, OpenCV expects `BGR` format frames in its `cv2.write()` method."
 
+!!! note "The `YUV` pixel-format frames are NOT yet supported by OpenCV VideoWriter, try using WriteGear API instead."
+
 === "BGR frames"
 
     ```python
@@ -106,8 +108,8 @@ In this example we will decode different pixel formats video frames from a given
 
     # prepare OpenCV parameters
     FOURCC = cv2.VideoWriter_fourcc("M", "J", "P", "G")
-    FRAMERATE = metadata_dict["source_video_framerate"]
-    FRAMESIZE = tuple(metadata_dict["source_video_resolution"])
+    FRAMERATE = metadata_dict["output_framerate"]
+    FRAMESIZE = tuple(metadata_dict["output_frames_resolution"])
 
     # Define writer with parameters and suitable output filename for e.g. `output_foo.avi`
     writer = cv2.VideoWriter("output_foo.avi", FOURCC, FRAMERATE, FRAMESIZE)
@@ -159,8 +161,8 @@ In this example we will decode different pixel formats video frames from a given
 
     # prepare OpenCV parameters
     FOURCC = cv2.VideoWriter_fourcc("M", "J", "P", "G")
-    FRAMERATE = metadata_dict["source_video_framerate"]
-    FRAMESIZE = tuple(metadata_dict["source_video_resolution"])
+    FRAMERATE = metadata_dict["output_framerate"]
+    FRAMESIZE = tuple(metadata_dict["output_frames_resolution"])
 
     # Define writer with parameters and suitable output filename for e.g. `output_foo.avi`
     writer = cv2.VideoWriter("output_foo.avi", FOURCC, FRAMERATE, FRAMESIZE)
@@ -204,8 +206,8 @@ In this example we will decode different pixel formats video frames from a given
 
     # prepare OpenCV parameters
     FOURCC = cv2.VideoWriter_fourcc("M", "J", "P", "G")
-    FRAMERATE = metadata_dict["source_video_framerate"]
-    FRAMESIZE = tuple(metadata_dict["source_video_resolution"])
+    FRAMERATE = metadata_dict["output_framerate"]
+    FRAMESIZE = tuple(metadata_dict["output_frames_resolution"])
 
     # Define writer with parameters and suitable output filename for e.g. `output_foo_gray.avi`
     writer = cv2.VideoWriter("output_foo_gray.avi", FOURCC, FRAMERATE, FRAMESIZE)
@@ -229,50 +231,6 @@ In this example we will decode different pixel formats video frames from a given
     writer.release()
     ```
 
-=== "YUV frames"
-
-    !!! info "OpenCV also directly consumes `YUV` format frames in its `cv2.write()` method."
-
-    !!! note "You can also use `yuv422p`(4:2:2 subsampling) or `yuv444p`(4:4:4 subsampling) instead in `frame_format` parameter for more higher dynamic range."
-
-    ```python
-    # import the necessary packages
-    from deffcode import FFdecoder
-    import json, cv2
-
-    # initialize and formulate the decoder for YUV420 output
-    decoder = FFdecoder("foo.mp4", frame_format="yuv420p", verbose=True).formulate()
-
-    # retrieve JSON Metadata and convert it to dict
-    metadata_dict = json.loads(decoder.metadata)
-
-    # prepare OpenCV parameters
-    FOURCC = cv2.VideoWriter_fourcc("M", "J", "P", "G")
-    FRAMERATE = metadata_dict["source_video_framerate"]
-    FRAMESIZE = tuple(metadata_dict["source_video_resolution"])
-
-    # Define writer with parameters and suitable output filename for e.g. `output_foo_yuv.avi`
-    writer = cv2.VideoWriter("output_foo_yuv.avi", FOURCC, FRAMERATE, FRAMESIZE)
-
-    # grab the YUV420 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}
-
-        # writing YUV420 frame to writer
-        writer.write(frame)
-
-    # terminate the decoder
-    decoder.terminate()
-
-    # safely close writer
-    writer.release()
-    ```
-
 &nbsp;
 
 ## Transcoding lossless video using WriteGear API
@@ -421,9 +379,11 @@ In this example we will decode different pixel formats video frames from a given
 
 === "YUV frames"
 
-    !!! info "WriteGear API also directly consumes `YUV` format frames in its `write()` class method. 
+    !!! info "WriteGear API can easily consumes `YUV` format frames in its `write()` class method only in compression mode."
+
+    !!! note "You can also use `yuv422p`(4:2:2 subsampling) or `yuv444p`(4:4:4 subsampling) instead for more higher dynamic ranges."
 
-    !!! note "You can also use `yuv422p`(4:2:2 subsampling) or `yuv444p`(4:4:4 subsampling) instead in `frame_format` parameter for more higher dynamic range."
+    !!! alert "In WriteGear API, the support for `-input_pixfmt` attribute in `output_params` dictionary parameter was added in `v0.3.0`."
 
     ```python
     # import the necessary packages
@@ -432,17 +392,19 @@ In this example we will decode different pixel formats video frames from a given
     import json
 
     # initialize and formulate the decoder for YUV420 output
-    decoder = FFdecoder("foo.mp4", frame_format="yuv420p", verbose=True).formulate()
+    decoder = FFdecoder("foo.mp4", frame_format="yuv420p").formulate()
 
-    # retrieve framerate from source JSON Metadata and pass it as `-input_framerate` parameter
-    # for controlled output framerate
+    # retrieve framerate from source JSON Metadata and pass it as 
+    # `-input_framerate` parameter for controlled framerate
+    # and add input pixfmt as yuv420p also
     output_params = {
-        "-input_framerate": json.loads(decoder.metadata)["source_video_framerate"]
+        "-input_framerate": json.loads(decoder.metadata)["output_framerate"],
+        "-input_pixfmt": "yuv420p"
     }
 
     # Define writer with default parameters and suitable
     # output filename for e.g. `output_foo_yuv.mp4`
-    writer = WriteGear(output_filename="output_foo_yuv.mp4", **output_params)
+    writer = WriteGear(output_filename="output_foo_yuv.mp4", logging=True, **output_params)
 
     # grab the YUV420 frame from the decoder
     for frame in decoder.generateFrame():
diff --git a/docs/reference/ffdecoder/params.md b/docs/reference/ffdecoder/params.md
index 58b9429..c4bd4c8 100644
--- a/docs/reference/ffdecoder/params.md
+++ b/docs/reference/ffdecoder/params.md
@@ -104,7 +104,50 @@ Its valid input can be one of the following:
 
     !!! example "Related usage recipes :material-pot-steam: can found [here ➶](../../../recipes/basic/decode-network-streams/#decoding-network-streams)"
 
-- [x] **Video Capture Devices (Webcams):** Valid video capture device's name _(e.g. `"USB2.0 Camera"`)_ or its path _(e.g. `"/dev/video0"` on linux)_ or its index _(e.g. `"0"`)_ as input  w.r.t [`source_demuxer`](#source_demuxer) parameter value in use. For example, for capturing `"USB2.0 Camera"` named device with `dshow` source demuxer on :fontawesome-brands-windows: Windows, we can do as follows in FFdecoder API: 
+- [x] **Camera Device Index:** Valid "device index" or "camera index" of the connected Camera Device. One can easily Capture desired Camera Device in FFdecoder API by specifying its matching index value _(use Sourcer API's [`enumerate_devices`](../../../reference/sourcer/#deffcode.sourcer.Sourcer.enumerate_devices) to list them)_ either as **integer** or **string of integer** type to its `source` parameter. For example, for capturing `"0"` index device on :fontawesome-brands-windows: Windows, we can do as follows in FFdecoder API: 
+
+    ??? danger "Requirement for Index based Camera Device Capturing in FFdecoder API"
+
+        - [x] **MUST have appropriate FFmpeg binaries, Drivers, and Softwares installed:**
+            
+            Internally, DeFFcode APIs achieves Index based Camera Device Capturing by employing some specific FFmpeg demuxers on different platforms(OSes). These platform specific demuxers are as follows:
+
+            | Platform(OS) | Demuxer |
+            |:------------:|:-------|
+            | :fontawesome-brands-windows: Windows OS|[`dshow`](https://trac.ffmpeg.org/wiki/DirectShow) _(or DirectShow)_ |
+            | :material-linux: Linux OS | [`video4linux2`](https://trac.ffmpeg.org/wiki/Capture/Webcam#Linux) _(or its alias `v4l2`)_ |
+            | :material-apple: Mac OS | [`avfoundation`](https://ffmpeg.org/ffmpeg-devices.html#avfoundation) |
+
+            **:warning: Important:** Kindly make sure your FFmpeg binaries support these platform specific demuxers as well as system have the appropriate video drivers and related softwares installed.
+        - [x] The [`source`](#source) parameter value **MUST be exactly the probed Camera Device index** _(use Sourcer API's [`enumerate_devices`](../../../reference/sourcer/#deffcode.sourcer.Sourcer.enumerate_devices) to list them)_.
+        - [x] The [`source_demuxer`](#source_demuxer) parameter value  **MUST be either `None`_(also means empty)_ or `"auto"`**. 
+
+    ??? tip "Important Facts related to Camera Device Indexing"
+        - [x] **Camera Device indexes are 0-indexed**. So the first device is at `0`, second is at `1`, so on. So if the there are `n` devices, the last device is at `n-1`.
+        - [x] **Camera Device indexes can be of either integer** _(e.g. `0`,`1`, etc.)_ or **string of integer** _(e.g. `"0"`,`"1"`, etc.)_ **type**.
+        - [x] **Camera Device indexes can be negative** _(e.g. `-1`,`-2`, etc.)_, this means you can also start indexing from the end.
+            * For example, If there are three devices: 
+                ```python
+                {0: 'Integrated Camera', 1: 'USB2.0 Camera', 2: 'DroidCam Source'}
+                ```
+            * Then, You can specify Positive Indexes and its Equivalent Negative Indexes as follows:
+
+                | Positive Indexes | Equivalent Negative Indexes |
+                |:------------:|:-------:|
+                | `#!python FFdecoder("0").formulate()`| `#!python FFdecoder("-3").formulate()` |
+                | `#!python FFdecoder("1").formulate()`| `#!python FFdecoder("-2").formulate()` |
+                | `#!python FFdecoder("2").formulate()`| `#!python FFdecoder("-1").formulate()` |
+
+        !!! warning "Out of Index Camera Device index values will raise `ValueError` in FFdecoder API"
+
+    ```python
+    # initialize and formulate the decoder with "0" index source for BGR24 output
+    decoder = FFdecoder("0", frame_format="bgr24", verbose=True).formulate()
+    ```
+
+    !!! example "Related usage recipes :material-pot-steam: can found [here ➶](../../../recipes/basic/decode-camera-devices)"
+
+- [x] **Video Capture Device Name/Path:** Valid video capture device's name _(e.g. `"USB2.0 Camera"`)_ or its path _(e.g. `"/dev/video0"` on linux)_ or its index _(e.g. `"0"`)_ as input  w.r.t [`source_demuxer`](#source_demuxer) parameter value in use. For example, for capturing `"USB2.0 Camera"` named device with `dshow` source demuxer on :fontawesome-brands-windows: Windows, we can do as follows in FFdecoder API: 
 
     ??? tip "Identifying and Specifying Device name/path/index and suitable Demuxer on different OSes"
 
@@ -404,12 +447,30 @@ Its valid input can be one of the following:
 
 ## **`source_demuxer`** 
 
-This parameter specifies the demuxer(`-f`) for the input source _(such as `dshow`, `v4l2`, `gdigrab` etc.)_ to support Live Feed Devices, as well as `lavfi` _(Libavfilter input virtual device)_ that reads data from the open output pads of a libavfilter filtergraph. 
+This parameter specifies the demuxer(`-f`) for the input source _(such as `dshow`, `v4l2`, `gdigrab` etc.)_ to support Live Feed Devices, `lavfi` _(Libavfilter input virtual device)_ that reads data from the open output pads of a libavfilter filtergraph, and  
 
 !!! warning "Any invalid or unsupported value to `source_demuxer` parameter value will raise `Assertion` error!"
 
 !!! tip "Use `#!sh ffmpeg -demuxers` terminal command to lists all FFmpeg supported demuxers."
 
+??? info "Specifying `source_demuxer` for Index based Camera Device Capturing in FFdecoder API"
+    
+    For enabling Index based Camera Device Capturing in FFdecoder API, the `source_demuxer` parameter value  **MUST be either `None`_(also means empty)_ or `"auto"`:**
+    
+    === "`source_demuxer=None` _(Default and Recommended)_"
+        ```python
+        # initialize and formulate the decoder with "0" index source for BGR24 output
+        decoder = FFdecoder("0", frame_format="bgr24").formulate()
+        ```
+    === "`source_demuxer="auto"`"
+        ```python
+        # initialize and formulate the decoder with "0" index source for BGR24 output
+        decoder = FFdecoder("0", source_demuxer="auto, frame_format="bgr24").formulate()
+        ```
+
+    !!! example "Related usage recipes :material-pot-steam: can found [here ➶](../../../recipes/basic/decode-camera-devices)"
+
+
 **Data-Type:** String
 
 **Default Value:** Its default value is `None`.
@@ -427,23 +488,34 @@ decoder = FFdecoder("foo.mp4", source_demuxer="dshow").formulate()
 
 ## **`frame_format`** 
 
-This parameter select the pixel format for output video frames _(such as `gray` for grayscale output)_. If not specified, its value defaults to `rgb24` _(24-bit RGB)_.
+This parameter select the pixel format for output video frames _(such as `gray` for grayscale output)_.
 
-!!! warning "Any invalid or unsupported value to `frame_format` parameter will discarded!"
+??? note "Any invalid or unsupported value to `frame_format` parameter will discarded!"
+
+    Any improper `frame_format` parameter value _(i.e. either `null`(special-case), undefined, or invalid type)_ , then `-pix_fmt` FFmpeg parameter value in Decoding pipeline uses `output_frames_pixfmt` metadata property extracted from Output Stream. Thereby, in case if no valid `output_frames_resolution`  metadata property is found, then API finally defaults to **Default pixel-format**[^1] _(calculated variably)_.
+
+    !!! alert "The `output_frame_pixfmt` metadata property is only available when FFmpeg filters via. `-vf` or `-filter_complex` are manually defined."
+
+
+??? info "Use `#!py3 frame_format="null"` to manually discard `-pix_fmt` FFmpeg parameter entirely from Decoding pipeline."
+
+    This feature allows users to manually skip `-pix_fmt` FFmpeg parameter in Decoding pipeline, essentially for using only `format` filter values, or even better, let FFmpeg itself choose the best available output frame pixel-format for the given source.
 
-!!! tip "Use `#!sh ffmpeg -pix_fmts` terminal command to lists all FFmpeg supported pixel formats."
 
 **Data-Type:** String
 
-**Default Value:** Its default value is `rgb24`
+**Default Value:** Its default value is **Default pixel-format**[^1] _(calculated variably)_.
 
 **Usage:**
 
+
 ```python
 # initialize and formulate the decoder for grayscale frames
 decoder = FFdecoder("foo.mp4", frame_format="gray").formulate()
 ```
 
+!!! tip "Use `#!sh ffmpeg -pix_fmts` terminal command to lists all FFmpeg supported pixel formats."
+
 !!! example "Various Pixel formats related usage recipes :material-pot-steam: can found [here ➶](../../../recipes/basic/decode-video-files/#capturing-and-previewing-bgr-frames-from-a-video-file)"
 
 &nbsp; 
@@ -486,7 +558,7 @@ FFdecoder("foo.mp4", custom_ffmpeg="/foo/foo1/ffmpeg").formulate()
 
 ## **`verbose`**
 
-This parameter enables verbose _(if `True`)_, essential for debugging. 
+This parameter enables verbose logs _(if `True`)_, essential for debugging. 
 
 **Data-Type:** Boolean
 
@@ -495,6 +567,7 @@ This parameter enables verbose _(if `True`)_, essential for debugging.
 **Usage:**
 
 ```python
+# initialize and formulate decoder with verbose logs
 FFdecoder("foo.mp4", verbose=True).formulate()
 ```
 
@@ -534,16 +607,17 @@ decoder = FFdecoder("foo.mp4", verbose=True, **ffparams).formulate()
 
 #### B. Exclusive Parameters
 
-> In addition to FFmpeg parameters, FFdecoder API also supports few Exclusive Parameters, to allow users to flexibly change its internal pipeline, properties, and handle some special FFmpeg parameters _(such as repeated `map`)_ that cannot be assigned via. python dictionary. 
+> In addition to FFmpeg parameters, FFdecoder API also supports few Exclusive Parameters to allow users to flexibly change its internal pipeline, properties, and handle some special FFmpeg parameters _(such as repeated `map`)_ that cannot be assigned via. python dictionary. 
 
 These parameters are discussed below:
 
-
 * **`-vcodec`** _(str)_ : This attribute works similar to `-vcodec` FFmpeg parameter for specifying supported decoders that are compiled with FFmpeg in use. If not specified, it's value is derived from source video metadata. Its usage is as follows: 
 
     !!! tip "Use `#!sh ffmpeg -decoders` terminal command to lists all FFmpeg supported decoders."
 
-    !!! info "To remove `-vcodec` forcefully from FFmpeg Pipeline, assign its value Nonetype as `#!py3 {"-vcodec":None}` in ffparams"
+    ??? info "Use `#!py3 {"-vcodec":None}` in ffparams to discard `-vcodec` FFmpeg parameter entirely from Decoding pipeline."
+
+        This feature allows users to manually skip `-vcodec` FFmpeg parameter in Decoding pipeline, for letting FFmpeg itself choose the best available video decoder for the given source.
 
     ```python
     # define suitable parameter
@@ -553,7 +627,19 @@ These parameters are discussed below:
 &ensp;
 
 
-* **`-framerate`** _(float/int)_ : This attribute works similar to `-framerate` FFmpeg parameter for generating video-frames at specified framerate. If not specified, it calculated from source video metadata. Its usage is as follows: 
+* **`-framerate`** _(float/int)_ : This attribute works similar to `-framerate` FFmpeg parameter for generating video-frames at specified framerate. If not specified, it calculated from video metadata. Its usage is as follows: 
+
+    ??? note "Any invalid or unsupported value to `-framerate` attribute will discarded!"
+
+        !!! alert "The `output_frames_framerate` metadata property is only available when FFmpeg filters via. `-vf` or `-filter_complex` are manually defined."
+
+        Any improper `-framerate` parameter value _(i.e. either `null`(special-case), undefined, or invalid type)_ , then `-framerate/-r` FFmpeg parameter value in Decoding pipeline uses `output_frames_framerate` metadata property extracted from Output Stream. Thereby, in case if no valid `output_framerate`  metadata property is found, then API finally defaults to `source_video_framerate` metadata property extracted from Input Source Stream.
+
+        !!! fail "In case neither `output_framerate` nor `source_video_framerate` valid metadata properties are found, then `RuntimeError` is raised."
+
+    ??? info "Use `#!py3 {"-framerate":"null"}` in ffparams to discard `-framerate/-r` FFmpeg parameter entirely from Decoding pipeline."
+
+        This feature allows users to manually skip `-framerate/-r` FFmpeg parameter in Decoding pipeline, essentially for using only `fps` filter values, or even better, let FFmpeg itself choose the best available output framerate for the given source.
 
     ```python
     # define suitable parameter
@@ -562,7 +648,19 @@ These parameters are discussed below:
 
 &ensp;
 
-* **`-custom_resolution`** _(tuple/list)_ : This attribute sets the custom resolution/size/dimensions of the output frames. Its value can either be a **tuple** => `(width,height)` or a **list** => `[width, height]`. If not specified, it calculated from source video metadata. Its usage is as follows: 
+* **`-custom_resolution`** _(tuple/list)_ : This attribute sets the custom resolution/size of the output frames. Its value can either be a **tuple** (`(width,height)`) or a **list** (`[width, height]`). If not specified, it calculated from video metadata. Its usage is as follows: 
+
+    ??? note "Any invalid or unsupported value to `-custom_resolution` attribute will discarded!"
+
+        !!! alert "The `output_frames_resolution` metadata property is only available when FFmpeg filters via. `-vf` or `-filter_complex` are manually defined."
+
+        Any improper `-custom_resolution` parameter value _(i.e. either `null`(special-case), undefined, or invalid type)_ , then `-s/-size` FFmpeg parameter value in Decoding pipeline uses `output_frames_resolution` metadata property extracted from Output Stream. Thereby, in case if no valid `output_frames_resolution`  metadata property is found, then API finally defaults to `source_video_resolution` metadata property extracted from Input Source Stream.
+
+        !!! fail "In case neither `output_frames_resolution` nor `source_video_resolution` valid metadata properties are found, then `RuntimeError` is raised."
+
+    ??? info "Use `#!py3 {"-custom_resolution":"null"}` in ffparams to discard `-size/-s` FFmpeg parameter entirely from Decoding pipeline."
+
+        This feature allows users to manually skip `-size/-s` FFmpeg parameter in Decoding pipeline, essentially for using only `fps` filter values, or even better, let FFmpeg itself choose the best available output frames resolution for the given source.
     
     ```python
     # define suitable parameter
@@ -603,7 +701,7 @@ These parameters are discussed below:
 
 &ensp;
 
-* **`-custom_sourcer_params`** _(dict)_ :  This attribute assigns parameter meant for Sourcer API's [`sourcer_params`](../../sourcer/params/#sourcer_params) dictionary parameter, directly through FFdecoder API. Its usage is as follows: 
+* **`-custom_sourcer_params`** _(dict)_ :  This attribute assigns all [**Exclusive Parameter**](../../sourcer/params/#exclusive-parameters) meant for Sourcer API's `sourcer_params` dictionary parameter directly through FFdecoder API. Its usage is as follows: 
     
     ```python
     # define suitable parameter meant for `sourcer_params`
@@ -612,10 +710,29 @@ These parameters are discussed below:
 
 &ensp;
 
+* **`-default_stream_indexes`** _(list/tuple)_ : This attribute assign value directly to `default_stream_indexes` parameter in Sourcer API's [`probe_stream()`](../../../reference/sourcer/#deffcode.sourcer.Sourcer.probe_stream) method for selecting specific video and audio stream index in case of multiple ones. Value can be of format: `(int,int)` or `[int,int]` as follows:
+    
+    ```python
+    # define suitable parameter meant for `probe_stream()` method
+    ffparams = {"-default_stream_indexes": (0,1)} # ("0th video stream", "1st audio stream")
+    ```
+
+&ensp;
+
 * **`-passthrough_audio`** _(bool/list)_ : _(Yet to be supported)_
 
 &nbsp; 
 
+[^1]: **Default pixel-format** is calculated variably in FFdecoder API:
+      
+      - [x] If `frame_format != "null"`: 
+        - If `frame_format` parameter is valid and supported: Default pixel-format is `frame_format` parameter value.
+        - If `frame_format` parameter is **NOT** valid or supported:
+            - If `output_frame_pixfmt` metadata is available: Default pixel-format is `output_frame_pixfmt` metadata value.
+            - If `output_frame_pixfmt` metadata is **NOT** available: Default pixel-format is `rgb24` if supported otherwise `source_video_pixfmt` metadata value.
+      - [x] If `frame_format == "null"`: Default pixel-format is `source_video_pixfmt` metadata value
+
+
 <!--
 External URLs
 -->
diff --git a/docs/reference/sourcer/params.md b/docs/reference/sourcer/params.md
index 5761fea..5fe78f4 100644
--- a/docs/reference/sourcer/params.md
+++ b/docs/reference/sourcer/params.md
@@ -98,8 +98,32 @@ Its valid input can be one of the following:
     sourcer = Sourcer('rtsp://xx:yy@192.168.1.ee:fd/av0_0', verbose=True, **sourcer_params).probe_stream()
     ```
 
+- [x] **Camera Device Index:** Valid "device index" or "camera index" of the connected Camera Device. For example, for using `"0"` index device as source on :fontawesome-brands-windows: Windows, we can do as follows in Sourcer API: 
 
-- [x] **Video Capture Devices (Webcams):** Valid video probe device's name _(e.g. `"USB2.0 Camera"`)_ or its path _(e.g. `"/dev/video0"` on linux)_ or its index _(e.g. `"0"`)_ as input  w.r.t [`source_demuxer`](#source_demuxer) parameter value in use. For example, for probing `"USB2.0 Camera"` named device with `dshow` source demuxer on :fontawesome-brands-windows: Windows, we can do as follows in Sourcer API: 
+    ??? danger "Requirement for using Camera Device as source in Sourcer API"
+
+        - [x] **MUST have appropriate FFmpeg binaries, Drivers, and Softwares installed:**
+            
+            Internally, DeFFcode APIs achieves Index based Camera Device Capturing by employing some specific FFmpeg demuxers on different platforms(OSes). These platform specific demuxers are as follows:
+
+            | Platform(OS) | Demuxer |
+            |:------------:|:-------|
+            | :fontawesome-brands-windows: Windows OS|[`dshow`](https://trac.ffmpeg.org/wiki/DirectShow) _(or DirectShow)_ |
+            | :material-linux: Linux OS | [`video4linux2`](https://trac.ffmpeg.org/wiki/Capture/Webcam#Linux) _(or its alias `v4l2`)_ |
+            | :material-apple: Mac OS | [`avfoundation`](https://ffmpeg.org/ffmpeg-devices.html#avfoundation) |
+
+            **:warning: Important:** Kindly make sure your FFmpeg binaries support these platform specific demuxers as well as system have the appropriate video drivers and related softwares installed.
+
+        - [x] The [`source`](#source) parameter value **MUST be any Camera Device index** that can be of either **integer** _(e.g. `-1`,`0`,`1`, etc.)_ or **string of integer** _(e.g. `"-1"`,`"0"`,`"1"`, etc.)_ type.
+
+        - [x] The [`source_demuxer`](#source_demuxer) parameter value  **MUST be either `None`_(also means empty)_ or `"auto"`**. 
+
+    ```python
+    # initialize the sourcer with "0" index source and probe it
+    sourcer = Sourcer("0", verbose=True).probe_stream()
+    ```
+
+- [x] **Video Capture Devices:** Valid video probe device's name _(e.g. `"USB2.0 Camera"`)_ or its path _(e.g. `"/dev/video0"` on linux)_ or its index _(e.g. `"0"`)_ as input  w.r.t [`source_demuxer`](#source_demuxer) parameter value in use. For example, for probing `"USB2.0 Camera"` named device with `dshow` source demuxer on :fontawesome-brands-windows: Windows, we can do as follows in Sourcer API: 
 
     ??? tip "Identifying and Specifying Device name/path/index and suitable Demuxer on different OSes"
 
@@ -323,6 +347,21 @@ This parameter specifies the demuxer(`-f`) for the input source _(such as `dshow
 
 !!! tip "Use `#!sh ffmpeg -demuxers` terminal command to lists all FFmpeg supported demuxers."
 
+??? info "Specifying `source_demuxer` for using Camera Device Index as source in Sourcer API"
+    
+    For using Camera Device Index as source in Sourcer API, the `source_demuxer` parameter value  **MUST be either `None`_(also means empty)_ or `"auto"`:**
+    
+    === "`source_demuxer=None` _(Default and Recommended)_"
+        ```python
+        # initialize the sourcer with "0" index source and probe it
+        sourcer = Sourcer("0").probe_stream()
+        ```
+    === "`source_demuxer="auto"`"
+        ```python
+        # initialize the sourcer with "0" index source and probe it
+        sourcer = Sourcer("0", source_demuxer="auto).probe_stream()
+        ```
+
 **Data-Type:** String
 
 **Default Value:** Its default value is `None`.
@@ -375,7 +414,7 @@ Sourcer("foo.mp4", custom_ffmpeg="/foo/foo1/ffmpeg").probe_stream()
 
 ## **`verbose`**
 
-This parameter enables verbose _(if `True`)_, essential for debugging. 
+This parameter enables verbose logs _(if `True`)_, essential for debugging. 
 
 **Data-Type:** Boolean
 
@@ -384,6 +423,7 @@ This parameter enables verbose _(if `True`)_, essential for debugging.
 **Usage:**
 
 ```python
+# initialize the sourcer with verbose logs
 Sourcer("foo.mp4", verbose=True).probe_stream()
 ```
 
@@ -394,49 +434,24 @@ Sourcer("foo.mp4", verbose=True).probe_stream()
 
 This dictionary parameter accepts all [Exclusive Parameters](#exclusive-parameters) formatted as its attributes:
 
+???+ note "Additional FFmpeg parameters"
+    
+    In addition to Exclusive Parameters, Sourcer API supports almost any FFmpeg parameter _(supported by installed FFmpeg)_, and thereby can be passed as dictionary attributes in `sourcer_params` parameter.
+
+    !!! danger "Kindly read [**FFmpeg Docs**](https://ffmpeg.org/documentation.html) carefully before passing any additional values to `sourcer_params` parameter. Wrong invalid values may result in undesired errors or no output at all."
+
+    !!! alert "All FFmpeg parameters are case-sensitive. Remember to double check every parameter if any error(s) occurred."
+
 **Data-Type:** Dictionary
 
 **Default Value:** Its default value is `{}`.
 
 ### Exclusive Parameters
 
-> In addition to FFmpeg parameters, Sourcer API also supports few Exclusive Parameters, to allow users to flexibly change its probing properties, and handle some special FFmpeg parameters.
+> Sourcer API supports few Exclusive Parameters to allow users to flexibly change its probing properties and handle some special FFmpeg parameters.
 
 These parameters are discussed below:
 
-
-* **`-vcodec`** _(str)_ : This attribute works similar to `-vcodec` FFmpeg parameter for specifying supported decoders that are compiled with FFmpeg in use. If not specified, it's value is derived from source video metadata. Its usage is as follows: 
-
-    !!! tip "Use `#!sh ffmpeg -decoders` terminal command to lists all FFmpeg supported decoders."
-
-    !!! info "To remove `-vcodec` forcefully from FFmpeg Pipeline, assign its value Nonetype as `#!py3 {"-vcodec":None}` in sourcer_params"
-
-    ```python
-    # define suitable parameter
-    sourcer_params = {"-vcodec": "h264"} # set decoder to `h264`
-    ```
-
-&ensp;
-
-
-* **`-framerate`** _(float/int)_ : This attribute works similar to `-framerate` FFmpeg parameter for generating video-frames at specified framerate. If not specified, it calculated from source video metadata. Its usage is as follows: 
-
-    ```python
-    # define suitable parameter
-    sourcer_params = {"-framerate": 60.0} # set input video source framerate to 60fps
-    ```
-
-&ensp;
-
-* **`-custom_resolution`** _(tuple/list)_ : This attribute sets the custom resolution/size/dimensions of the output frames. Its value can either be a **tuple** => `(width,height)` or a **list** => `[width, height]`. If not specified, it calculated from source video metadata. Its usage is as follows: 
-    
-    ```python
-    # define suitable parameter
-    sourcer_params = {"-output_dimensions": (1280,720)} # to produce a 1280x720 resolution/scale output video
-    ```
-
-&ensp;
-
 * **`-ffprefixes`** _(list)_: This attribute sets the special FFmpeg parameters that generally occurs at the very beginning _(such as `-re`)_ before input (`-i`) source. The FFmpeg parameters defined with this attribute can repeated more than once and maintains its original order in the FFmpeg command. Its value can be of datatype **`list`** only and its usage is as follows: 
 
     !!! tip "Turn on [`verbose`](#verbose) parameter _(`verbose = True`)_ to see the FFmpeg command that is being executed in Sourcer's pipeline. This helps you debug/address any issues and make adjustments accordingly."
diff --git a/mkdocs.yml b/mkdocs.yml
index 23fd4eb..f585a01 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -173,7 +173,7 @@ nav:
     - Basic Recipes: 
       - Overview: recipes/basic/index.md
       - Decoding Video Files: recipes/basic/decode-video-files.md
-      - Decoding Live Feed Devices: recipes/basic/decode-live-feed-devices.md
+      - Decoding Camera Devices: recipes/basic/decode-camera-devices.md
       - Decoding Network Streams: recipes/basic/decode-network-streams.md
       - Decoding Image sequences: recipes/basic/decode-image-sequences.md
       - Transcoding Live frames: recipes/basic/transcode-live-frames.md 
@@ -183,6 +183,7 @@ nav:
     - Advanced Recipies: 
       - Overview: recipes/advanced/index.md
       - Decoding Live Virtual Sources: recipes/advanced/decode-live-virtual-sources.md
+      - Decoding Live Feed Devices: recipes/advanced/decode-live-feed-devices.md
       - Hardware-Accelerated Video Decoding: recipes/advanced/decode-hw-acceleration.md
       - Transcoding Live Complex Filtergraphs: recipes/advanced/transcode-live-frames-complexgraphs.md
       - Transcoding Video Art with Filtergraphs: recipes/advanced/transcode-art-filtergraphs.md
diff --git a/scripts/bash/prepare_dataset.sh b/scripts/bash/prepare_dataset.sh
index c9a7aa8..d702cad 100644
--- a/scripts/bash/prepare_dataset.sh
+++ b/scripts/bash/prepare_dataset.sh
@@ -92,11 +92,15 @@ curl -L https://github.com/abhiTronix/Imbakup/releases/download/vid-001/jellyfis
 echo "Done Downloading Test-Data!"
 
 if [ $OS_NAME = "linux" ]; then
+  echo "Create undeleteable file for testing"
+  touch undelete.txt
+  sudo chattr +i - v "$TMPFOLDER"/Downloads/Test_videos/undelete.txt
   echo "Preparing images from video"
   ffmpeg -i "$TMPFOLDER"/Downloads/Test_videos/BigBuckBunny_4sec_VO.mp4 "$TMPFOLDER"/temp_images/out%d.png
   echo "Setting up ffmpeg v4l2loopback"
-  sudo modprobe v4l2loopback devices=1 video_nr=2 exclusive_caps=1 card_label='VCamera'
-  sudo v4l2-ctl --list-devices
-  nohup sudo ffmpeg -hide_banner -re -stream_loop -1 -i "$TMPFOLDER"/Downloads/Test_videos/BigBuckBunny_4sec_VO.mp4 -f v4l2 -pix_fmt yuv420p /dev/video2 &
+  sudo modprobe v4l2loopback devices=1 video_nr=0 exclusive_caps=1 card_label='VCamera'
+  nohup sudo ffmpeg -hide_banner -loglevel error -re -stream_loop -1 -i "$TMPFOLDER"/Downloads/Test_videos/BigBuckBunny_4sec_VO.mp4 -f v4l2 -pix_fmt yuv420p /dev/video0 &
+  echo "$USER ALL=NOPASSWD:$(which v4l2-ctl)" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/v4l2ctl')
+  v4l2-ctl --list-devices
   echo "Done"
 fi
diff --git a/setup.py b/setup.py
index c2019aa..fdc4207 100644
--- a/setup.py
+++ b/setup.py
@@ -23,20 +23,16 @@
 from setuptools import setup
 from distutils.util import convert_path
 
+# parse PKG version
 pkg_version = {}
 ver_path = convert_path("deffcode/version.py")
 with open(ver_path) as ver_file:
     exec(ver_file.read(), pkg_version)
 
+# apply various patches to README text and prepare
+# valid long_description
 with open("README.md", "r", encoding="utf-8") as fh:
     long_description = fh.read()
-    # patch internal hyperlinks
-    long_description = long_description.replace(
-        "(#", "(https://github.com/abhiTronix/deffcode#"
-    )
-    long_description = long_description.replace(
-        "docs/overrides/", "https://abhitronix.github.io/deffcode/latest/"
-    )
     # patch to remove github README specific text
     long_description = (
         long_description.replace(
@@ -49,13 +45,20 @@
     )
     # patch for unicodes
     long_description = long_description.replace("➶", ">>").replace("©", "(c)")
+    # patch internal hyperlinks
+    long_description = long_description.replace(
+        "(#", "(https://github.com/abhiTronix/deffcode#"
+    )
+    long_description = long_description.replace(
+        "docs/overrides/", "https://abhitronix.github.io/deffcode/latest/"
+    )
 
 
 setup(
     name="deffcode",
     packages=["deffcode"],
     version=pkg_version["__version__"],
-    description="A Cross-platform High-performance & Flexible Video Frames Decoder in python.",
+    description="A cross-platform High-performance & Flexible Real-time Video Frames Decoder in Python.",
     license="Apache License 2.0",
     author="Abhishek Thakur",
     install_requires=[


Test patch:
diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py
index 66a104e..887a245 100644
--- a/tests/test_ffdecoder.py
+++ b/tests/test_ffdecoder.py
@@ -80,7 +80,7 @@ def test_source_playback(source, custom_ffmpeg, output):
                 verbose=True,
             )
             # force unknown number of frames(like camera) {special case}
-            instance.metadata = {"approx_video_nframes": 0}
+            instance.metadata = {"approx_video_nframes": 0, "source_has_audio": True}
             # formulate decoder
             decoder = instance.formulate()
         else:
@@ -171,8 +171,8 @@ def test_frame_format(pixfmts):
                     "John",
                     ("inner_tuple"),
                 ),
-                "output_frames_pixfmt": 1234, # invalid pixformat
-                "source_video_resolution": [640], # invalid resolution
+                "output_frames_pixfmt": 1234,  # invalid pixformat
+                "source_video_resolution": [640],  # invalid resolution
             },
             False,
         ),
@@ -204,7 +204,7 @@ def test_metadata(custom_params, checks):
     source = return_testvideo_path(fmt="vo")
     try:
         # custom vars
-        ffparams = {"-framerate": None} if not checks else {}
+        ffparams = {"-framerate": None} if not checks else {"-framerate": 25.0}
         # formulate the decoder with suitable source(for e.g. foo.mp4)
         decoder = FFdecoder(
             source, custom_ffmpeg=return_static_ffmpeg(), verbose=True, **ffparams
@@ -244,6 +244,7 @@ def test_metadata(custom_params, checks):
                 "-ss": "00:00:01.45",
                 "-frames:v": 1,
                 "-custom_resolution": [640, 480],
+                "-framerate": 30.0,
                 "-passthrough_audio": "invalid",  # just for test
                 "-vcodec": "unknown",
             },
@@ -254,6 +255,7 @@ def test_metadata(custom_params, checks):
                 "-ss": "00:02.45",
                 "-vframes": 1,
                 "-custom_resolution": "invalid",
+                "-framerate": "invalid",
                 "-ffprefixes": "invalid",
                 "-clones": "invalid",
                 "-framerate": "invalid",
@@ -313,7 +315,7 @@ def test_seek_n_save(ffparams, pixfmts):
         filename and remove_file_safe(filename)
 
 
-test_data_class = [
+test_data = [
     (return_testvideo_path(), {"-c:v": "hevc"}, False),
     (
         return_generated_frames_path(return_static_ffmpeg()),
@@ -326,8 +328,9 @@ def test_seek_n_save(ffparams, pixfmts):
         True,
     ),
     (
-        return_testvideo_path(),
+        "testsrc=size=1280x720:rate=30",  # virtual "testsrc" source
         {
+            "-ffprefixes": ["-t", "5"],  # playback time of 5 seconds
             "-clones": [
                 "-i",
                 "https://abhitronix.github.io/deffcode/latest/assets/images/ffmpeg.png",
@@ -339,7 +342,7 @@ def test_seek_n_save(ffparams, pixfmts):
 ]
 
 
-@pytest.mark.parametrize("source, ffparams, result", test_data_class)
+@pytest.mark.parametrize("source, ffparams, result", test_data)
 def test_FFdecoder_params(source, ffparams, result):
     """
     Testing FFdecoder API with different parameters and save output
@@ -349,7 +352,14 @@ def test_FFdecoder_params(source, ffparams, result):
     f_name = os.path.join(*[tempfile.gettempdir(), "temp_write", "output_foo.avi"])
     try:
         # initialize and formulate the decode with suitable source
-        with FFdecoder(source, frame_format="bgr24", **ffparams) as decoder:
+        with FFdecoder(
+            source,
+            frame_format="bgr24",
+            source_demuxer="lavfi"
+            if (isinstance(source, str) and source.startswith("testsrc"))
+            else None,
+            **ffparams,
+        ) as decoder:
 
             # retrieve JSON Metadata and convert it to dict
             metadata_dict = json.loads(decoder.metadata)
@@ -378,33 +388,163 @@ def test_FFdecoder_params(source, ffparams, result):
             pytest.xfail(str(e))
     finally:
         # terminate the decoder
-        not (writer is None) and writer.release() and remove_file_safe(f_name)
+        if not (writer is None):
+            writer.release()
+            remove_file_safe(f_name)
 
 
-@pytest.mark.skipif(
-    (platform.system() != "Linux"),
-    reason="This test not supported yet on platforms other than Linux!",
-)
-def test_camera_capture():
+test_data = [
+    (
+        "/dev/video0",
+        "v4l2",
+        True if platform.system() == "Linux" else False,
+    ),  # manual source and demuxer
+    (
+        0,
+        None,
+        True if platform.system() in ["Linux", "Darwin"] else False,
+    ),  # +ve index and no demuxer
+    (
+        "-1",
+        "auto",
+        True if platform.system() in ["Linux", "Darwin"] else False,
+    ),  # -ve index and "auto" demuxer
+    ("5", "auto", False),  # out-of-range index and "auto" demuxer
+    ("invalid", "auto", False),  # invalid source and "auto" demuxer
+    ("/dev/video0", "invalid", False),  # manual source and invalid demuxer
+]
+
+
+@pytest.mark.parametrize("source, source_demuxer, result", test_data)
+def test_camera_capture(source, source_demuxer, result):
     """
-    Tests FFdecoder's realtime camera playback capabilities
+    Tests FFdecoder's realtime Webcam and Virtual playback capabilities
+    as well as Index based Camera Device Capturing
     """
     decoder = None
     try:
         # initialize and formulate the decode with suitable source
         decoder = FFdecoder(
-            "/dev/video2", source_demuxer="v4l2", frame_format="bgr24"
+            source,
+            source_demuxer=source_demuxer,
+            frame_format="bgr24",
+            verbose=True,
         ).formulate()
-        # capture 10 camera frames
-        for i in range(10):
+        # capture 5 camera frames
+        for i in range(5):
             # grab the bgr24 frame from the decoder
             frame_recv = next(decoder.generateFrame(), None)
             # check if frame is None
             if frame_recv is None:
                 raise AssertionError("Test Failed!")
     except Exception as e:
-        # catch errors
-        pytest.fail(str(e))
+        if result:
+            # catch errors
+            pytest.fail(str(e))
+        else:
+            pytest.xfail(str(e))
+    finally:
+        # terminate
+        not (decoder is None) and decoder.terminate()
+
+
+test_data = [
+    (
+        "null",  # discard frame_format
+        {
+            "-custom_resolution": "null",  # discard `-custom_resolution`
+            "-framerate": "null",  # discard `-framerate`
+            "-vf": "format=bgr24,scale=320:240,fps=60",  # format=bgr24, scale=320x240, framerate=60fps
+        },
+        True,
+    ),
+    (
+        "bgr24",  # this pixel-format must override filter `format=rgb24`
+        {
+            "-vf": "format=rgb24,scale=320:240,fps=60",  # format=rgb24, scale=320x240, framerate=60fps
+        },
+        True,
+    ),
+    (
+        "invalid",  # invalid frame_format
+        {
+            "-custom_resolution": "invalid",  # invalid `-custom_resolution`
+            "-framerate": "invalid",  # invalid `-framerate`
+            "-vf": "format=bgr24,scale=320:240,fps=60",  # format=bgr24, scale=320x240, framerate=60fps
+        },
+        True,
+    ),
+    (
+        "invalid2",  # invalid frame_format
+        {
+            "-custom_resolution": "invalid",  # invalid `-custom_resolution`
+            "-framerate": "null",  # discard `-framerate`
+        },
+        False,
+    ),
+    (
+        "invalid3",  # invalid frame_format
+        {
+            "-custom_resolution": "null",  # discard `-custom_resolution`
+            "-framerate": "invalid",  # invalid `-framerate`
+        },
+        False,
+    ),
+    (
+        "null",  # discard frame_format
+        {
+            "-custom_resolution": "null",  # discard `-custom_resolution`
+            "-framerate": "null",  # discard `-framerate`
+        },
+        True,
+    ),
+]
+
+
+@pytest.mark.parametrize("frame_format, ffparams, result", test_data)
+def test_discard_n_filter_params(frame_format, ffparams, result):
+    """
+    Tests FFdecoder's discarding FFmpeg parameters and using FFmpeg Filter
+    capabilities
+    """
+    decoder = None
+    try:
+        # initialize and formulate the decode with suitable source
+        if not frame_format in ["invalid2", "invalid3"]:
+            decoder = FFdecoder(
+                return_testvideo_path(),
+                frame_format=frame_format,
+                verbose=True,
+                **ffparams,
+            ).formulate()
+        else:
+            decoder = FFdecoder(
+                return_testvideo_path(),
+                frame_format=frame_format,
+                verbose=True,
+                **ffparams,
+            )
+            # assign manually pix-format via `metadata` property object {special case}
+            decoder.metadata = (
+                {"source_video_resolution": [0], "output_frames_resolution": [0]}
+                if frame_format == "invalid2"
+                else {"source_video_framerate": 0.0, "output_framerate": 0.0}
+            )
+            # formulate decoder
+            decoder.formulate()
+        # capture 2 camera frames
+        for i in range(2):
+            # grab the bgr24 frame from the decoder
+            frame_recv = next(decoder.generateFrame(), None)
+            # check if frame is None
+            if frame_recv is None:
+                raise AssertionError("Test Failed!")
+    except Exception as e:
+        if result:
+            # catch errors
+            pytest.fail(str(e))
+        else:
+            pytest.xfail(str(e))
     finally:
         # terminate
         not (decoder is None) and decoder.terminate()
diff --git a/tests/test_ffhelper.py b/tests/test_ffhelper.py
index 181aaa5..7822925 100644
--- a/tests/test_ffhelper.py
+++ b/tests/test_ffhelper.py
@@ -40,6 +40,7 @@
     is_valid_image_seq,
     is_valid_url,
     check_sp_output,
+    extract_device_n_demuxer,
 )
 
 # define test logger
@@ -141,7 +142,7 @@ def test_get_valid_ffmpeg_path(paths, ffmpeg_download_paths, results):
 @pytest.mark.xfail(raises=Exception)
 def test_check_sp_output():
     """
-    Testing validation function of WebGear API
+    Testing check_sp_output method
     """
     check_sp_output(["ffmpeg", "-Vv"])
 
@@ -156,7 +157,7 @@ def test_check_sp_output():
 )
 def test_is_valid_url(URL, result):
     """
-    Testing is_valid_url function
+    Testing is_valid_url method
     """
     try:
         result_url = is_valid_url(return_static_ffmpeg(), url=URL, verbose=True)
@@ -179,7 +180,7 @@ def test_is_valid_url(URL, result):
 )
 def test_is_valid_image_seq(source, result):
     """
-    Testing test_is_valid_image_seq function
+    Testing test_is_valid_image_seq method
     """
     try:
         result_url = is_valid_image_seq(
@@ -199,10 +200,18 @@ def test_is_valid_image_seq(source, result):
 )
 def test_validate_imgseqdir(path, result):
     """
-    Testing validate_imgseqdir function
+    Testing validate_imgseqdir method
     """
     try:
         output = validate_imgseqdir(path, extension="png", verbose=True)
         assert output == result, "Image sequence directory validity test Failed!"
     except Exception as e:
         result and pytest.fail(str(e))
+
+
+@pytest.mark.xfail(raises=ValueError)
+def test_extract_device_n_demuxer():
+    """
+    Testing extract_device_n_demuxer method
+    """
+    extract_device_n_demuxer(return_static_ffmpeg(), machine_OS="invalid", verbose=True)
\ No newline at end of file
diff --git a/tests/test_sourcer.py b/tests/test_sourcer.py
index b1b7a5b..0fc7b01 100644
--- a/tests/test_sourcer.py
+++ b/tests/test_sourcer.py
@@ -108,18 +108,28 @@ def test_probe_stream_n_retrieve_metadata(source, default_stream_indexes, params
     Test `probe_stream` and `retrieve_metadata` function.
     """
     try:
+        source_demuxer = (
+            "lavfi" if source == "mandelbrot=size=1280x720:rate=30" else None
+        )
         if source == "invalid":
             sourcer = Sourcer(
                 source, custom_ffmpeg=return_static_ffmpeg(), verbose=True
             )
         else:
             sourcer = Sourcer(
-                source, custom_ffmpeg=return_static_ffmpeg(), verbose=True
+                source,
+                custom_ffmpeg=return_static_ffmpeg(),
+                source_demuxer=source_demuxer,
+                verbose=True,
             ).probe_stream(default_stream_indexes=default_stream_indexes)
         metadata = sourcer.retrieve_metadata()
         logger.debug("Found Metadata: `{}`".format(metadata))
         assert all(metadata[x] == True for x in params), "Test Failed!"
-        if source.startswith("http") or source.endswith("png"):
+        if (
+            source.startswith("http")
+            or source.endswith("png")
+            or source == "mandelbrot=size=1280x720:rate=30"
+        ):
             logger.debug("Skipped check!")
         else:
             assert (
@@ -127,7 +137,7 @@ def test_probe_stream_n_retrieve_metadata(source, default_stream_indexes, params
                 >= actual_frame_count_n_frame_size(source)[0]
             ), "Test Failed for frames count!"
     except Exception as e:
-        if isinstance(e, (ValueError, ValueError)) or (
+        if isinstance(e, ValueError) or (
             source in ["invalid", "unknown://invalid.com/"]
             and isinstance(e, AssertionError)
         ):
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 956d6a4..4a28286 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -22,11 +22,12 @@
 import pytest
 import logging
 import os
+import tempfile
 from os.path import expanduser
 from deffcode.utils import dict2Args, logger_handler, delete_file_safe
 
 # define test logger
-logger = logging.getLogger("Test_utils")
+logger = logging.getLogger("Test_Utilities")
 logger.propagate = False
 logger.addHandler(logger_handler())
 logger.setLevel(logging.DEBUG)
@@ -85,11 +86,21 @@ def test_dict2Args(dictionary):
         pytest.fail("Failed to complete this test!")
 
 
-def test_delete_file_safe():
+test_data = [
+    (os.path.join(expanduser("~"), "invalid"), True),
+    ("{}/Downloads/Test_videos/{}".format(tempfile.gettempdir(), "undelete.txt"), False),
+]
+
+
+@pytest.mark.parametrize("file_path, result", test_data)
+def test_delete_file_safe(file_path, result):
     """
     Testing delete_file_safe method
     """
     try:
-        delete_file_safe(os.path.join(expanduser("~"), "invalid"))
+        delete_file_safe(file_path)
     except Exception as e:
-        pytest.fail(str(e))
+        if result:
+            pytest.fail(str(e))
+        else:
+            pytest.xfail(str(e))