Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Develop #37

Merged
merged 62 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
74294f0
Merge pull request #21 from amiaopensource/feature/find_bitdepth
eddycolloton Sep 26, 2024
b010f80
changing framesList froma circular buffer to a regular list to get i…
eddycolloton Sep 27, 2024
2dae67e
fixed typo, extra comma in calling detectBars function
eddycolloton Sep 30, 2024
d4df78d
put circular buffer back in to framesList, found good 10bit thresholds
eddycolloton Sep 30, 2024
d8429f8
removed durationStart and durationStop from barsDetection output. Can…
eddycolloton Sep 30, 2024
e1cc571
added conditional for different bars detection thresholds for 8bit vs…
eddycolloton Sep 30, 2024
f476419
Merge branch 'develop' into feature/new_barsdetection
eddycolloton Sep 30, 2024
82a6b0b
Merge pull request #22 from amiaopensource/feature/new_barsdetection
eddycolloton Sep 30, 2024
c472ada
adding color bars evaluation funciton, after color bars detection.
eddycolloton Sep 30, 2024
39709c2
added -be to README
eddycolloton Oct 1, 2024
7ddeecf
Merge pull request #23 from amiaopensource/feature/evaluate_bars
eddycolloton Oct 1, 2024
3f1a6d8
removed print('') statements with \n
eddycolloton Oct 1, 2024
0673ca9
adding asci colors to print results, and args conditional statement t…
eddycolloton Oct 1, 2024
054a876
made print_peak_colorbars() function
eddycolloton Oct 2, 2024
88d821c
small spell check changes
eddycolloton Oct 2, 2024
62a9fae
Merge pull request #24 from amiaopensource/feature/revised_output
eddycolloton Oct 2, 2024
1e78130
New README
eddycolloton Oct 3, 2024
cf933cf
Removing applescript grep code from README
eddycolloton Oct 3, 2024
d1cc944
adding support for extracting report from mkvs
eddycolloton Oct 3, 2024
ff56d34
added input files and logging sections to README
eddycolloton Oct 4, 2024
3b0f653
small change to the logging docstring
eddycolloton Oct 4, 2024
478ed76
noted support for both 8 and 10 bit in README
eddycolloton Oct 4, 2024
88d3050
small adjustments to white space in readme
eddycolloton Oct 4, 2024
90e7e41
Merge pull request #25 from amiaopensource/feature/new_readme
eddycolloton Oct 4, 2024
c614f55
Merge pull request #26 from amiaopensource/feature/extract_qct_from_mkv
eddycolloton Oct 4, 2024
907c63d
added exit() if report extraction from MKV fails
eddycolloton Oct 4, 2024
4178651
added exit() if thumbnail path is specified but thumbnail export is not
eddycolloton Oct 4, 2024
15aff56
adding ffprobe detection of resolution for thumbnail size
eddycolloton Oct 4, 2024
9756a30
added -update 1 to ffmpeg command to supress ffmpeg warning expecting…
eddycolloton Oct 4, 2024
e1c8a6d
Merge pull request #27 from amiaopensource/feature/detect_res_for_thumb
eddycolloton Oct 4, 2024
db5b217
allowing for multiple profiles to be provided to -p arg
eddycolloton Oct 7, 2024
b68697e
small updates to README
eddycolloton Oct 8, 2024
2e56e77
confirms specified profile matches one of the config sections, and th…
eddycolloton Oct 12, 2024
bea7aaf
Merge pull request #28 from amiaopensource/feature/multiple_profiles
eddycolloton Oct 12, 2024
b7099aa
modifying analyzeIt, threshFinder, and how -o and -u args are parsed …
eddycolloton Oct 12, 2024
8dd9551
small changes to parser help output
eddycolloton Oct 13, 2024
660195a
throw error if over and under options are used together
eddycolloton Oct 13, 2024
b1a5245
Merge pull request #29 from amiaopensource/feature/new_threshFinder
eddycolloton Oct 13, 2024
4bb57e5
small change to comments spacing
eddycolloton Dec 3, 2024
59f59a5
qct-parse is now packagable
henryborchers Dec 3, 2024
24ffa01
Merge remote-tracking branch 'upstream/develop' into packaging
henryborchers Dec 3, 2024
198c2df
config file location is set with an environment variable
henryborchers Dec 3, 2024
2b4d44a
GitHub actions tests codes across all supported versions of python
henryborchers Dec 3, 2024
0c4fdda
support tox tool for testing
henryborchers Dec 3, 2024
2cd3f9b
QCT_PARSE_CONFIG_DIRECTORY is now optional environment variable
henryborchers Dec 3, 2024
7b554d1
Merge pull request #30 from henryborchers/packaging
eddycolloton Dec 3, 2024
49f142b
Merge remote-tracking branch 'upstream/develop' into github-actions
henryborchers Dec 3, 2024
eb5bd9c
Merge pull request #31 from henryborchers/github-actions
eddycolloton Dec 3, 2024
a1055a4
add initial test
henryborchers Dec 3, 2024
751d8e5
Add tag definitions to README
aeschweik Dec 3, 2024
99a0c0b
Merge pull request #32 from henryborchers/support-testing
eddycolloton Dec 3, 2024
b7f57a8
split main function into get_arg_parser and parse_qc_tools_report fun…
henryborchers Dec 3, 2024
a772459
Merge pull request #33 from aeschweik/develop
eddycolloton Dec 3, 2024
b610d5a
updates to README to reflect today's changes
eddycolloton Dec 3, 2024
a45f9c8
more README updates
eddycolloton Dec 4, 2024
c568e84
qct-parse can have multiple inputs
henryborchers Dec 4, 2024
94d88a3
Merge pull request #34 from henryborchers/dev
eddycolloton Dec 4, 2024
1739307
Support creation of Sphinx documentation
henryborchers Dec 4, 2024
aae1968
Merge pull request #35 from henryborchers/sphinx-docs
eddycolloton Dec 4, 2024
8d11924
added csv output option w/ -csv arg
eddycolloton Dec 4, 2024
f93f176
Merge pull request #36 from amiaopensource/feature/print_to_csv_v2
eddycolloton Dec 4, 2024
fdaccfb
resolving merge conflicts
eddycolloton Dec 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
on: [push, pull_request]
name: Supported Python Compatibility Test
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-2019]
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
include:
- os: macos-latest
- os: ubuntu-latest
- os: windows-2019
fail-fast: false
name: Python ${{ matrix.python-version }} ${{ matrix.os }} build
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip' # caching pip dependencies
- name: Install requirements
run: |
pip install tox
- uses: actions/github-script@v7
id: tox-env
with:
result-encoding: string
script: |
const frontend = "${{matrix.frontend}}"
const toxEnv = "py${{matrix.python-version}}".replace('.','')
if(frontend === ""){
return toxEnv
}
return "py${{matrix.python-version}}".replace('.','') + "-${{matrix.frontend}}"
- name: Run tox
run: tox -e ${{ steps.tox-env.outputs.result }}
237 changes: 173 additions & 64 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,102 +1,211 @@
scripts for automating QCTools actions

qct-parse.py | find frames that are beyond thresholds for saturation, luma, etc
# QCTools Automation Scripts

This repository contains scripts for automating analysis of QCTools reports.

## Overview

### Install from source:

* Create a new Python Virtual Environment for qct_parse
* Unix based (Mac or Linux):
`python3 -m venv name_of_env`
* Windows:
`py -m venv name_of_env`
(where 'name_of_env' is replaced with the name of your virtual environment)
* Activate virtual env
* Unix based (Mac or Linux):
`source ./name_of_env/bin/activate`
* Windows:
`name_of_env\scripts\activate`
* Install Package
* Navigate to the repo root directory `path/to/qct-parse/`
* Run the command:
`python -m pip install .`

### Test Code

If you intend to develop the code for your proposes or contribute to the open source project, a test directory is provided in the repo.
* Activate virtual env (see Install from source)
* Install pytest
`pip install pytest`
* Run tests
`python -m pytest`

### Building the documentation
* Activate virtual env (see Install from source)
* Install sphinx and myst-parser
`pip install sphinx myst-parser`
* Run sphinx-build command
`sphinx-build ./docs ./dist/docs`


### Commands:

- **`qct-parse -i/--input [path to QCTools report] [optional arguments]`**
Finds frames that exceed thresholds for QCTool tag(s). Full list of command line arguments below.

---

# `qct-parse`

Run a single tag against a supplied value or multiple tags using a profile.

## Arguments

makeqctoolsreport.py | make a qctools.xml.gz report for input video file
| Argument | Description |
|-----------------------------|-------------------------------------------------------------------------------------------------------|
| `-h`, `--help` | Show this help message and exit |
| `-i`, `--input` | Path to the input `qctools.xml.gz` or `qctools.mkv` file |
| `-t`, `--tagname` | The tag name you want to test (e.g., `SATMAX`); see table of tag names below for list |
| `-o`, `--over` | Threshold overage number |
| `-u`, `--under` | Threshold under number |
| `-p`, `--profile` | Compare frame data against tag values from `config.txt`. Use `-p default` for QCTools default values |
| `-buff`, `--buffSize` | Circular buffer size. If even, defaults to the next odd number (default: 11) |
| `-te`, `--thumbExport` | Enable/disable thumbnail export (default: off) |
| `-ted`, `--thumbExportDelay`| Minimum frames between exported thumbnails (default: 9000) |
| `-tep`, `--thumbExportPath` | Path to thumbnail export. Uses input base-path if omitted |
| `-ds`, `--durationStart` | Start analysis from this time (seconds, equivalent to ffmpeg `-ss`) |
| `-de`, `--durationEnd` | End analysis after this time (seconds, equivalent to ffmpeg `-t`) |
| `-bd`, `--barsDetection` | Enable/disable bar detection (default: off) |
| `-be`, `--barsEvaluation` | Use peak values from color bars as 'profile' if bars are detected |
| `-pr`, `--print` | Print over/under frame data to console (default: off) |
| `-q`, `--quiet` | Suppress ffmpeg output in console (default: off) |

# qct-parse.py
## Tags

You can run a single tag against a supplied value from the CLI or run multiple tags against values set in the qct-parse_config.txt file.
| Tag category | Tag names |
|-----------------------------|-------------------------------------------------------------------------------------------------------|
| [YUV values](https://bavc.github.io/qctools/filter_descriptions.html#yuv) | `YMIN,YLOW,YAVG,YHIGH,YMAX`<br>`UMIN,ULOW,UAVG,UHIGH,UMAX`<br>`VMIN,VLOW,VAVG,VHIGH,VMAX` |
| [YUV values (difference)](https://bavc.github.io/qctools/filter_descriptions.html#diff) | `YDIF,UDIF,VDIF` |
| [Saturation values](https://bavc.github.io/qctools/filter_descriptions.html#saturation) | `SATMIN,SATLOW,SATAVG,SATHIGH,SATMAX` |
| [Hue values](https://bavc.github.io/qctools/filter_descriptions.html#hue) | `HUEMED,HUEAVG` |
| [Temporal outliers](https://bavc.github.io/qctools/filter_descriptions.html#tout) | `TOUT` |
| [Vertical line repetitions](https://bavc.github.io/qctools/filter_descriptions.html#vrep) | `VREP` |
| [Broadcast range](https://bavc.github.io/qctools/filter_descriptions.html#brng) | `BRNG` |
| [Mean square error fields](https://bavc.github.io/qctools/filter_descriptions.html#msef) | `mse_y,mse_u,mse_v,mse_avg` |
| [Peak signal to noise ratio fields](https://bavc.github.io/qctools/filter_descriptions.html#psnrf) | `psnr_y,psnr_u,psnr_v,psnr_avg` |

## arguments
-h, --help | show this help message and exit
## Examples

-i, --input | the path to the input qctools.xml.gz file

-t, --tagname | the tag name you want to test, e.g. SATMAX

-o, --over | the threshold overage number

-u, --under | the threshold under number

-p, --profile | compare frame data aginst tag values from config.txt file, us "-p default" for values from QCTools docs

-buff, --buffSize | Size of the circular buffer. if user enters an even number it'll default to the next largest number to make it odd, default size 11

-te, --thumbExport | export thumbnails on/ off, default off

-ted, --thumbExportDelay | minimum frames between exported thumbs, default 9000

-tep, --thumbExportPath | Path to thumb export. if ommitted, uses the input base-path

-ds, --durationStart | the duration in seconds to start analysis (ffmpeg equivalent -ss)

-de, --durationEnd | the duration in seconds to stop analysis (ffmpeg equivalent -t)

-bd, --barsDetection | bar detection on/ off, default off

-pr, --print | print over/under frame data to console window, default off

-q, --quiet | print ffmpeg output to console window, default off
### Run single tag tests
```bash
qct-parse -t SATMAX -o 235 -t YMIN -u 16 -i /path/to/report.mkv.qctools.xml.gz
```

### Run bars detection using default QCTools profile
```bash
qct-parse -bd -p default -i /path/to/report.mkv.qctools.mkv
```

## examples
### Export thumbnails of frames beyond threshold
```bash
qct-parse -p default -te -tep /path/to/export/folder -i /path/to/report.mkv.qctools.xml.gz
```

### single tags
### Use peak values from detected color bars as thresholds
```bash
qct-parse -bd -be -i /path/to/report.mkv.qctools.xml.gz
```

python qct-parse.py -t SATMAX -o 235 -t YMIN -u 16 -i /path/to/report.mkv.qctools.xml.gz
## Input files

### run bars against default profile from QCTools docs
qct-parse.py will work with the following QCTools report formats:
```
qctools.xml.gz
qctools.mkv
```

python qct-parse.py -bd -p default -i /path/to/reportsmkv.qctools.xml.gz
If the qctools.xml.gz report is in an MKV attachment, the qctools.xml.gz report file will be extracted and saved as a separate file.

### print out thumbnails of frames beyond threshold
Both 8-bit and 10-bit values are supported. The bit depth will be detected automatically, and does not need to be specified.

python qct-parse.py -p default -te -tep C:\path\to\export\folder -i C:\path\to\the\report.mkv.qctools.xml.gz
## Config Files

## some handy applescript to grep individual tags
The provided profiles are:
* default
* highTolerance
* midTolerance
* lowTolerance

### just percentages
Each of these profiles contain the following tags with a corresponding threshold:
`YLOW, YMAX, UMIN, UMAX, VMIN, VMAX, SATMAX, TOUT, VREP`

python ./qct-parse.py -i input.mxf.qctools.xml.gz -bd -p lowTolerance | grep 'YMAX' | awk 'NR==1 {print $3}'
The profiles are stored in the config.txt files. Please note that there is a separate config.txt for 8-bit and 10-bit values.

### total number of frame failures
The process for providing user supplied profiles is in development.
Currently, if you wish to create your own profile, you will need to create your own config directory and `config.txt` file.
There is a environmental variable at the top of qct-parse.py which can be used to reset the config directory:
```bash
CONFIG_ENVIRONMENT_VARIABLE_NAME = 'QCT_PARSE_CONFIG_DIRECTORY'
```
Simply place the full path to the user created config *directory* in place of 'QCT_PARSE_CONFIG_DIRECTORY'

python ./qct-parse.py -i input.mxf.qctools.xml.gz -bd -p lowTolerance | grep 'YMAX' | awk 'NR==1 {print $2}'
## Thumbnails

## dependencies
Thumbnails of failed frames will be exported if the `-te` flag is invoked.

Python 2.7.x.
In order to export thumbnails, the QCTools report must be in the same directory as the video file it is describing, and must have the same file name as the report (excluding the `qctools.xml.gz`).

Requires that [lxml](http://lxml.de/) is installed on your system. For more info on how it's used, see [here](http://www.ibm.com/developerworks/library/x-hiperfparse/)
If you would like to provide a path for exporting thumbnails, you can do so using the `-tep` flag.
Otherwise, thumbnails will automatically be created in the same directory as the video file and QCTools report, in a new directory.

### For Windows users:
When running qct-parse with a profile, the thumbnails will be placed in a directory named `ThumbExports`.
When run against single tags the directory will be named [TAG NAME].[THRESHOLD]

We **strongly** suggest using the pre-compiled installer found [here](https://pypi.python.org/pypi/lxml/3.3.3#downloads)
## Logging

### For Mac users:
A log file is created with the same name as the input file but with a '.log' extension.
For example: `some_video_file.mkv.qctools.xml.gz.log`

Try pip first, then try the macport. More info can be found [here](http://lxml.de/installation.html)
Log files contain every instance of values over the specified threshold. For example:
`2024-10-03 17:02:35,737 SATMAX is over 181.02 with a value of 698.0 at duration 00:00:16.4500`

# makeqctoolsreport.py
---

python port of Morgan's [makeqctoolsreport.as](https://github.com/iamdamosuzuki/QCToolsReport)
### Legacy Commands:

Not in active development. Please file an issue if you are interested in using these.

## example
#### `makeqctoolsreport`

python makeqctoolsreport.py /path/to/input.mxf
A Python port of Morgan’s [makeqctoolsreport.as](https://github.com/iamdamosuzuki/QCToolsReport), this script generates QCTools `.xml.gz` reports from input video files.

## contributors
Example Usage:
```bash
makeqctoolsreport /path/to/input.mxf
```

@eddycolloton
#### `overcatch`

@CoatesBrendan
A script from the original qct-parse development for running a report against multiple profiles.

@av_morgan
Example Usage:
```bash
overcatch /path/to/input.mxf
```

## maintainers
---

@av_morgan
## Dependencies

@eddycolloton
Ensure Python 3.x.x is installed.

Requires FFmpeg.

This tool uses the `lxml` python module which is automatically installed with the qct-parse package.

For more information on `lxml` usage, check out the [lxml documentation](http://lxml.de/).

---

## Contributors

- [@eddycolloton](https://github.com/eddycolloton)
- [@CoatesBrendan](https://github.com/CoatesBrendan)
- [@av_morgan](https://github.com/av_morgan)

## Maintainer

- [@av_morgan](https://github.com/av_morgan)
- [@eddycolloton](https://github.com/eddycolloton)
20 changes: 20 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
31 changes: 31 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information

project = 'qct-parse'
copyright = '2024, AMIA Open-Source'
author = 'AMIA Open-Source'

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

extensions = ['myst_parser']

templates_path = ['_templates']
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']

source_suffix = {
'.rst': 'restructuredtext',
'.txt': 'markdown',
'.md': 'markdown',
}

# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output

html_theme = 'alabaster'
html_static_path = ['_static']
29 changes: 29 additions & 0 deletions docs/development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Development Information

## Configure Development Environment

* Create a new Python Virtual Environment for qct_parse
* Unix based (Mac or Linux):
`python3 -m venv name_of_env`
* Windows:
`py -m venv name_of_env`
(where 'name_of_env' is replaced with the name of your virtual environment)
* Activate virtual env
* Unix based (Mac or Linux):
`source ./name_of_env/bin/activate`
* Windows:
`name_of_env\scripts\activate`
* Install Package as editable package
* Navigate to the repo root directory `path/to/qct-parse/`
* Run the command:
`python -m pip install -e .`

## Run Tests

If you intend to develop the code for your proposes or contribute to the open source project, a test directory is provided in the repo.
* Activate virtual env (see Configure Development Environment)
* Install pytest
`pip install pytest`
* Run tests
`python -m pytest`

Loading
Loading