diff options
26 files changed, 495 insertions, 0 deletions
diff --git a/.github/workflows/hugo.yml b/.github/workflows/hugo.yml new file mode 100644 index 0000000..e26bd74 --- /dev/null +++ b/.github/workflows/hugo.yml @@ -0,0 +1,29 @@ +name: Deploy Hugo site to Pages + +on: + push: + branches: [master] + +permissions: + contents: write + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: peaceiris/actions-hugo@v3 + with: + hugo-version: 'latest' + extended: true + + - run: hugo --minify + + - uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./public + publish_branch: gh-pages + cname: kvog.sh + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a48cf0d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +public diff --git a/archetypes/default.md b/archetypes/default.md new file mode 100644 index 0000000..25b6752 --- /dev/null +++ b/archetypes/default.md @@ -0,0 +1,5 @@ ++++ +date = '{{ .Date }}' +draft = true +title = '{{ replace .File.ContentBaseName "-" " " | title }}' ++++ diff --git a/content/notes/ffmpeg.md b/content/notes/ffmpeg.md new file mode 100644 index 0000000..afc47e4 --- /dev/null +++ b/content/notes/ffmpeg.md @@ -0,0 +1,209 @@ ++++ +date = '2026-06-17T17:50:30-05:00' +title = 'FFmpeg' ++++ + +## Websites + +* [ffmpeg.org](https://ffmpeg.org/) +* [code.ffmpeg.org](https://code.ffmpeg.org/FFmpeg/FFmpeg) - code forge +* [trac.ffmpeg.org](https://trac.ffmpeg.org/query?status=!closed&type=defect&order=id&desc=1) - bug tracker, mostly abandoned in favor of forgejo +* [ffmpeg-devel mailing list](https://lists.ffmpeg.org/mailman3/lists/ffmpeg-devel.ffmpeg.org/) - development mailing list, mostly abandoned in favor of forgejo +* [ffmpeg-devel IRC](https://libera.catirclogs.org/ffmpeg-devel/2026-06) - development chat, very active +* [patchwork.ffmpeg.org](https://patchwork.ffmpeg.org/project/ffmpeg/list/) - archive of patches sent to ffmpeg-devel + +## Documentation + +* Command-line tools, filters, etc: https://ffmpeg.org/ffmpeg-all.html +* Component libraries: https://ffmpeg.org/doxygen/trunk/index.html + +## Building + +List all compile options: +``` +$ ./configure --help | vim - +``` + +Quick development build; takes about 90 seconds on an M1 MacBook Air: +``` +$ ./configure --disable-optimizations --disable-asm +$ make -j $(nproc) +$ make -j $(sysctl -n hw.logicalcpu) +``` + +Troubleshooting build: +``` +$ ./configure --disable-optimizations --assert-level=2 --toolchain=clang-asan +$ ./configure --disable-optimizations --assert-level=2 --toolchain=clang-asan-ubsan +``` + +`--enable-memory-poisoning` makes `av_malloc` and friends basically just do `memset(ptr, 0x2a, size)`. Does not add any asan-style bounds checking. + +## Regression testing + +FATE documentation: https://ffmpeg.org/fate.html, TLDR: +``` +$ ./configure --disable-optimizations --assert-level=2 --toolchain=clang-asan --samples=$HOME/Proj/FFmpeg-FATE +$ make +$ make fate-rsync +$ make fate +``` + +## Benchmarking + +checkasm docs: https://checkasm.videolan.me/ + +Build within FFmpeg: +``` +$ make checkasm +``` + +List tests: +``` +$ ./tests/checkasm/checkasm --list-tests | sort | vim - + +``` + +The easiest way to see what test calls what functions is to check the source code: +<br> +[`-> tests/checkasm/checkasm.c`](https://code.ffmpeg.org/FFmpeg/FFmpeg/src/branch/master/tests/checkasm/checkasm.c). + +Example: +``` +$ ./tests/checkasm/checkasm --bench --test=vf_bwdif +``` +<details> +<summary>Output</summary> + +``` +checkasm: + - CPU: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz (000906E9) + - Timing source: x86 (rdtsc) + - Bench duration: 1000 µs per function (4003730 cycles) + - Random seed: 2684063072 +C: + - vf_bwdif.bwdif8 [OK] + - vf_bwdif.bwdif10 [OK] + - vf_bwdif.bwdif8.line3 [OK] + - vf_bwdif.bwdif8.edge [OK] + - vf_bwdif.bwdif8.intra [OK] +SSE2: + - vf_bwdif.bwdif8 [OK] + - vf_bwdif.bwdif10 [OK] +SSSE3: + - vf_bwdif.bwdif8 [OK] + - vf_bwdif.bwdif10 [OK] +AVX2: + - vf_bwdif.bwdif8 [OK] + - vf_bwdif.bwdif10 [OK] +checkasm: all 6 tests passed +Benchmark results: + name cycles (vs ref) + bwdif8_c: 28876.2 + bwdif8_sse2: 1056.1 (25.12x) + bwdif8_ssse3: 870.5 (22.92x) + bwdif8_avx2: 550.6 (40.40x) + bwdif8.edge.s0.p0_c: 1373.2 + bwdif8.edge.s0.p1_c: 1310.2 + bwdif8.edge.s1.p0_c: 5368.5 + bwdif8.edge.s1.p1_c: 5824.8 + bwdif8.intra_c: 584.1 + bwdif8.line3.rnd.p0_c: 40020.9 + bwdif8.line3.rnd.p1_c: 30286.6 + bwdif10_c: 27988.9 + bwdif10_sse2: 935.6 (27.51x) + bwdif10_ssse3: 864.2 (27.04x) + bwdif10_avx2: 594.3 (36.53x) +``` + +</details> + +## libavformat architecture + +Note: This is all based off of FFmpeg 8.1.2 (commit `38b88335f99e76ed89ff3c93f877fdefce736c13`) + +Stepping through [`doc/examples/remux.c`](https://code.ffmpeg.org/FFmpeg/FFmpeg/src/commit/38b88335f99e76ed89ff3c93f877fdefce736c13/doc/examples/remux.c): + +<style> +.ffstackframe { + border-left: 2px solid #5555FF; + border-top: 1px solid #AAAAAA; + border-bottom: 1px solid #AAAAAA; + padding-left: 20px; +} +.ffstackframe > * { + margin-top: 0; + margin-bottom: 0; +} +</style> + +<div class="ffstackframe"> + +[`doc/examples/remux.c:75`](https://code.ffmpeg.org/FFmpeg/FFmpeg/src/commit/38b88335f99e76ed89ff3c93f877fdefce736c13/doc/examples/remux.c#L75): +`main` calls `avformat_open_input`. + + +<div class="ffstackframe"> + +[`libavformat/demux.c:241`](https://code.ffmpeg.org/FFmpeg/FFmpeg/src/commit/38b88335f99e76ed89ff3c93f877fdefce736c13/libavformat/demux.c#L241): +`avformat_open_input` calls `avformat_alloc_context` to allocate memory. + +[`libavformat/demux.c:266`](https://code.ffmpeg.org/FFmpeg/FFmpeg/src/commit/38b88335f99e76ed89ff3c93f877fdefce736c13/libavformat/demux.c#L266): +`avformat_open_input` calls `init_input`. + +<div class="ffstackframe"> + +[`libavformat/demux.c:185`](https://code.ffmpeg.org/FFmpeg/FFmpeg/src/commit/38b88335f99e76ed89ff3c93f877fdefce736c13/libavformat/demux.c#L185): +`init_input` calls `av_probe_input_buffer2`, which reads the first 2048 bytes of the input file +and passes it to `av_probe_input_format2`, which calls `avprobe_input_format3`. + +<div class="ffstackframe"> + +[`libavformat/format.c:175`](https://code.ffmpeg.org/FFmpeg/FFmpeg/src/commit/38b88335f99e76ed89ff3c93f877fdefce736c13/libavformat/format.c#L175): +`av_probe_input_format3` attemptes to locate id3 tags within the buffer + +[`libavformat/format.c:191`](https://code.ffmpeg.org/FFmpeg/FFmpeg/src/commit/38b88335f99e76ed89ff3c93f877fdefce736c13/libavformat/format.c#L191): +`av_probe_input_format3` iterates over each registered `FFInputFormat`, and calls the `probe` +function pointer, if present. `probe` takes the buffer and returns a score that represents how +likely the data matches that format. Some other factors are taken into account, such as the +extension of the file and what id3 tags were found. + +The most likely `AVInputFormat *` (composite class in `FFInputFormat`) is returned if found, +otherwise `NULL`. + +</div> + +[`libavformat/demux.c:305`](https://code.ffmpeg.org/FFmpeg/FFmpeg/src/commit/38b88335f99e76ed89ff3c93f877fdefce736c13/libavformat/demux.c#L305): +`init_input` allocates any private data required by the `FFInputFormat`. + +[`libavformat/demux.c:322`](https://code.ffmpeg.org/FFmpeg/FFmpeg/src/commit/38b88335f99e76ed89ff3c93f877fdefce736c13/libavformat/demux.c#L322): +`init_input` calls the `read_header` function pointer, if present. + +<div class="ffstackframe"> + +`read_header` will typically call `avformat_new_stream` to allocate streams. + +</div> + +[`libavformat/demux.c:355`](https://code.ffmpeg.org/FFmpeg/FFmpeg/src/commit/38b88335f99e76ed89ff3c93f877fdefce736c13/libavformat/demux.c#L355): +`init_input` calls the `update_stream_avctx`, which updates contexts for each stream. I am not sure +why this is needed since no codecs should be open at this point, only demuxing. + +<div class="ffstackframe"> + +[`libavformat/demux.c:194`](https://code.ffmpeg.org/FFmpeg/FFmpeg/src/commit/38b88335f99e76ed89ff3c93f877fdefce736c13/libavformat/demux.c#L194): +`update_stream_avctx` iterates over each detected stream and calls `avcodec_parameters_to_context` +if `FFStream->need_context_update == 1`. + +</div> +</div> + +To summarize, `avformat_open_input` probes the file to detect the container, initializes the +demuxer instance, and reads the file header. + +</div> + +[`doc/examples/remux.c:80`](https://code.ffmpeg.org/FFmpeg/FFmpeg/src/commit/38b88335f99e76ed89ff3c93f877fdefce736c13/doc/examples/remux.c#L80): +`main` calls `avformat_find_stream_info`. + +</div> diff --git a/hugo.toml b/hugo.toml new file mode 100644 index 0000000..fe72115 --- /dev/null +++ b/hugo.toml @@ -0,0 +1,7 @@ +baseURL = 'https://kvog.sh/' +locale = 'en-us' +title = 'kvog.sh' +theme = 'kvog' + +[markup.goldmark.renderer] + unsafe = true diff --git a/themes/kvog/archetypes/default.md b/themes/kvog/archetypes/default.md new file mode 100644 index 0000000..25b6752 --- /dev/null +++ b/themes/kvog/archetypes/default.md @@ -0,0 +1,5 @@ ++++ +date = '{{ .Date }}' +draft = true +title = '{{ replace .File.ContentBaseName "-" " " | title }}' ++++ diff --git a/themes/kvog/assets/css/components/footer.css b/themes/kvog/assets/css/components/footer.css new file mode 100644 index 0000000..abe2b5a --- /dev/null +++ b/themes/kvog/assets/css/components/footer.css @@ -0,0 +1,4 @@ +footer { + border-top: 1px solid #222; + margin-top: 1rem; +} diff --git a/themes/kvog/assets/css/components/header.css b/themes/kvog/assets/css/components/header.css new file mode 100644 index 0000000..8efea1e --- /dev/null +++ b/themes/kvog/assets/css/components/header.css @@ -0,0 +1,4 @@ +header { + border-bottom: 1px solid #222; + margin-bottom: 1rem; +} diff --git a/themes/kvog/assets/css/main.css b/themes/kvog/assets/css/main.css new file mode 100644 index 0000000..11744b1 --- /dev/null +++ b/themes/kvog/assets/css/main.css @@ -0,0 +1,15 @@ +@import "components/header.css"; +@import "components/footer.css"; + +body { + color: #222; + font-family: sans-serif; + line-height: 1.5; + margin: 1rem; + max-width: 1024px; +} + +a { + color: #00e; + text-decoration: none; +} diff --git a/themes/kvog/assets/js/main.js b/themes/kvog/assets/js/main.js new file mode 100644 index 0000000..e2aac52 --- /dev/null +++ b/themes/kvog/assets/js/main.js @@ -0,0 +1 @@ +console.log('This site was generated by Hugo.'); diff --git a/themes/kvog/content/_index.md b/themes/kvog/content/_index.md new file mode 100644 index 0000000..a3b8328 --- /dev/null +++ b/themes/kvog/content/_index.md @@ -0,0 +1,9 @@ ++++ +title = 'Home' +date = 2023-01-01T08:00:00-07:00 +draft = false ++++ + +This website is very messed up at the moment. Sorry. + +<marquee>🦍</marquee> diff --git a/themes/kvog/hugo.toml b/themes/kvog/hugo.toml new file mode 100644 index 0000000..a84662e --- /dev/null +++ b/themes/kvog/hugo.toml @@ -0,0 +1,32 @@ +baseURL = 'https://example.org/' +locale = 'en-US' +title = 'My New Hugo Project' + +[menus] + [[menus.main]] + name = 'Home' + pageRef = '/' + weight = 10 + +# [[menus.main]] +# name = 'Posts' +# pageRef = '/posts' +# weight = 20 + +# [[menus.main]] +# name = 'Notes' +# pageRef = '/notes' +# weight = 30 + +# [[menus.main]] +# name = 'Tags' +# pageRef = '/tags' +# weight = 40 + +[module] + [module.hugoVersion] + extended = false + min = '0.146.0' + +[markup.goldmark.renderer] + unsafe = true diff --git a/themes/kvog/layouts/_partials/footer.html b/themes/kvog/layouts/_partials/footer.html new file mode 100644 index 0000000..a7cd916 --- /dev/null +++ b/themes/kvog/layouts/_partials/footer.html @@ -0,0 +1 @@ +<p>Copyright {{ now.Year }}. All rights reserved.</p> diff --git a/themes/kvog/layouts/_partials/head.html b/themes/kvog/layouts/_partials/head.html new file mode 100644 index 0000000..02c2240 --- /dev/null +++ b/themes/kvog/layouts/_partials/head.html @@ -0,0 +1,5 @@ +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width"> +<title>{{ if .IsHome }}{{ site.Title }}{{ else }}{{ printf "%s | %s" .Title site.Title }}{{ end }}</title> +{{ partialCached "head/css.html" . }} +{{ partialCached "head/js.html" . }} diff --git a/themes/kvog/layouts/_partials/head/css.html b/themes/kvog/layouts/_partials/head/css.html new file mode 100644 index 0000000..8897866 --- /dev/null +++ b/themes/kvog/layouts/_partials/head/css.html @@ -0,0 +1,15 @@ +{{- with resources.Get "css/main.css" }} + {{- $opts := dict + "minify" (cond hugo.IsDevelopment false true) + "sourceMap" (cond hugo.IsDevelopment "linked" "none") + }} + {{- with . | css.Build $opts }} + {{- if hugo.IsDevelopment }} + <link rel="stylesheet" href="{{ .RelPermalink }}"> + {{- else }} + {{- with . | fingerprint }} + <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"> + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/themes/kvog/layouts/_partials/head/js.html b/themes/kvog/layouts/_partials/head/js.html new file mode 100644 index 0000000..0210efa --- /dev/null +++ b/themes/kvog/layouts/_partials/head/js.html @@ -0,0 +1,15 @@ +{{- with resources.Get "js/main.js" }} + {{- $opts := dict + "minify" (cond hugo.IsDevelopment false true) + "sourceMap" (cond hugo.IsDevelopment "linked" "none") + }} + {{- with . | js.Build $opts }} + {{- if hugo.IsDevelopment }} + <script src="{{ .RelPermalink }}"></script> + {{- else }} + {{- with . | fingerprint }} + <script src="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"></script> + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/themes/kvog/layouts/_partials/header.html b/themes/kvog/layouts/_partials/header.html new file mode 100644 index 0000000..7980a00 --- /dev/null +++ b/themes/kvog/layouts/_partials/header.html @@ -0,0 +1,2 @@ +<h1>{{ site.Title }}</h1> +{{ partial "menu.html" (dict "menuID" "main" "page" .) }} diff --git a/themes/kvog/layouts/_partials/menu.html b/themes/kvog/layouts/_partials/menu.html new file mode 100644 index 0000000..14245b5 --- /dev/null +++ b/themes/kvog/layouts/_partials/menu.html @@ -0,0 +1,51 @@ +{{- /* +Renders a menu for the given menu ID. + +@context {page} page The current page. +@context {string} menuID The menu ID. + +@example: {{ partial "menu.html" (dict "menuID" "main" "page" .) }} +*/}} + +{{- $page := .page }} +{{- $menuID := .menuID }} + +{{- with index site.Menus $menuID }} + <nav> + <ul> + {{- partial "inline/menu/walk.html" (dict "page" $page "menuEntries" .) }} + </ul> + </nav> +{{- end }} + +{{- define "_partials/inline/menu/walk.html" }} + {{- $page := .page }} + {{- range .menuEntries }} + {{- $attrs := dict "href" .URL }} + {{- if $page.IsMenuCurrent .Menu . }} + {{- $attrs = merge $attrs (dict "class" "active" "aria-current" "page") }} + {{- else if $page.HasMenuCurrent .Menu .}} + {{- $attrs = merge $attrs (dict "class" "ancestor" "aria-current" "true") }} + {{- end }} + {{- $name := .Name }} + {{- with .Identifier }} + {{- with T . }} + {{- $name = . }} + {{- end }} + {{- end }} + <li> + <a + {{- range $k, $v := $attrs }} + {{- with $v }} + {{- printf " %s=%q" $k $v | safeHTMLAttr }} + {{- end }} + {{- end -}} + >{{ $name }}</a> + {{- with .Children }} + <ul> + {{- partial "inline/menu/walk.html" (dict "page" $page "menuEntries" .) }} + </ul> + {{- end }} + </li> + {{- end }} +{{- end }} diff --git a/themes/kvog/layouts/_partials/terms.html b/themes/kvog/layouts/_partials/terms.html new file mode 100644 index 0000000..8a6ebec --- /dev/null +++ b/themes/kvog/layouts/_partials/terms.html @@ -0,0 +1,23 @@ +{{- /* +For a given taxonomy, renders a list of terms assigned to the page. + +@context {page} page The current page. +@context {string} taxonomy The taxonomy. + +@example: {{ partial "terms.html" (dict "taxonomy" "tags" "page" .) }} +*/}} + +{{- $page := .page }} +{{- $taxonomy := .taxonomy }} + +{{- with $page.GetTerms $taxonomy }} + {{- $label := (index . 0).Parent.LinkTitle }} + <div> + <div>{{ $label }}:</div> + <ul> + {{- range . }} + <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li> + {{- end }} + </ul> + </div> +{{- end }} diff --git a/themes/kvog/layouts/baseof.html b/themes/kvog/layouts/baseof.html new file mode 100644 index 0000000..7d17aa5 --- /dev/null +++ b/themes/kvog/layouts/baseof.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html lang="{{ site.Language.Locale }}" dir="{{ or site.Language.Direction `ltr` }}"> +<head> + {{ partial "head.html" . }} +</head> +<body> + <header> + {{ partial "header.html" . }} + </header> + <main> + {{ block "main" . }}{{ end }} + </main> + <footer> + {{ partial "footer.html" . }} + </footer> +</body> +</html> diff --git a/themes/kvog/layouts/home.html b/themes/kvog/layouts/home.html new file mode 100644 index 0000000..6d91f58 --- /dev/null +++ b/themes/kvog/layouts/home.html @@ -0,0 +1,11 @@ +{{ define "main" }} + {{ .Content }} + <!-- + {{ range site.RegularPages }} + <section> + <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> + {{ .Summary }} + </section> + {{ end }} + --> +{{ end }} diff --git a/themes/kvog/layouts/page.html b/themes/kvog/layouts/page.html new file mode 100644 index 0000000..7e286c8 --- /dev/null +++ b/themes/kvog/layouts/page.html @@ -0,0 +1,10 @@ +{{ define "main" }} + <h1>{{ .Title }}</h1> + + {{ $dateMachine := .Date | time.Format "2006-01-02T15:04:05-07:00" }} + {{ $dateHuman := .Date | time.Format ":date_long" }} + <time datetime="{{ $dateMachine }}">{{ $dateHuman }}</time> + + {{ .Content }} + {{ partial "terms.html" (dict "taxonomy" "tags" "page" .) }} +{{ end }} diff --git a/themes/kvog/layouts/section.html b/themes/kvog/layouts/section.html new file mode 100644 index 0000000..748f2f5 --- /dev/null +++ b/themes/kvog/layouts/section.html @@ -0,0 +1,10 @@ +{{ define "main" }} + <h1>{{ .Title }}</h1> + {{ .Content }} + {{ range .Pages }} + <section> + <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> + {{ .Summary }} + </section> + {{ end }} +{{ end }} diff --git a/themes/kvog/layouts/taxonomy.html b/themes/kvog/layouts/taxonomy.html new file mode 100644 index 0000000..c2e7875 --- /dev/null +++ b/themes/kvog/layouts/taxonomy.html @@ -0,0 +1,7 @@ +{{ define "main" }} + <h1>{{ .Title }}</h1> + {{ .Content }} + {{ range .Pages }} + <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> + {{ end }} +{{ end }} diff --git a/themes/kvog/layouts/term.html b/themes/kvog/layouts/term.html new file mode 100644 index 0000000..c2e7875 --- /dev/null +++ b/themes/kvog/layouts/term.html @@ -0,0 +1,7 @@ +{{ define "main" }} + <h1>{{ .Title }}</h1> + {{ .Content }} + {{ range .Pages }} + <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> + {{ end }} +{{ end }} diff --git a/themes/kvog/static/favicon.ico b/themes/kvog/static/favicon.ico Binary files differnew file mode 100644 index 0000000..67f8b77 --- /dev/null +++ b/themes/kvog/static/favicon.ico |