{"id":16721904,"url":"https://github.com/cnuernber/avclj","last_synced_at":"2025-06-26T09:39:47.946Z","repository":{"id":48349340,"uuid":"347466335","full_name":"cnuernber/avclj","owner":"cnuernber","description":"libavcodec pathways for Clojure.","archived":false,"fork":false,"pushed_at":"2021-12-03T19:41:42.000Z","size":280,"stargazers_count":59,"open_issues_count":2,"forks_count":3,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-01T10:02:53.026Z","etag":null,"topics":["clojure","ffmpeg","libavcodec"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cnuernber.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-03-13T19:59:36.000Z","updated_at":"2024-05-31T07:52:15.000Z","dependencies_parsed_at":"2022-09-01T12:12:04.481Z","dependency_job_id":null,"html_url":"https://github.com/cnuernber/avclj","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnuernber%2Favclj","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnuernber%2Favclj/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnuernber%2Favclj/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnuernber%2Favclj/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cnuernber","download_url":"https://codeload.github.com/cnuernber/avclj/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244160043,"owners_count":20408020,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure","ffmpeg","libavcodec"],"created_at":"2024-10-12T22:32:43.946Z","updated_at":"2025-03-21T21:30:42.476Z","avatar_url":"https://github.com/cnuernber.png","language":"Clojure","readme":"# FFmpeg (libavcodec) Bindings for Clojure\n\n[![Clojars Project](https://img.shields.io/clojars/v/com.cnuernber/avclj.svg)](https://clojars.org/com.cnuernber/avclj)\n\n* [API Documentation](https://cnuernber.github.io/avclj/)\n\n\nThis system uses the [ffi architecture](https://cnuernber.github.io/dtype-next/tech.v3.datatype.ffi.html) of dtype-next in order to build \nbindings to JNA, JDK-16 and Graal Native.\n\n\n## Usage\n\nYou must have libavcodec installed to use this library; it was already on my machine.\n\n```console\nlibavcodec58 - FFmpeg library with de/encoders for audio/video codecs - runtime files\n```\n\n```clojure\n   {cnuernber/avclj {:git/url \"https://github.com/cnuernber/avclj\"\n                     :sha \"HEAD\"}}\n```\n\n* [example encoder](test/avclj_test.clj)\n* [API documentation](https://cnuernber.github.io/avclj/)\n\n## Development\n\n* `clj -X:codox` - regenerate documentation\n* `clj -M:test` - run the unit tests\n\n\n## Graal Native\n\nI used the dtype-next [activate-graal](https://github.com/cnuernber/dtype-next/blob/master/scripts/activate-graal) script to activate graal native:\n\n```console\n(base) chrisn@chrisn-lt3:~/dev/cnuernber/dtype-next$ source scripts/activate-graal\n(base) chrisn@chrisn-lt3:~/dev/cnuernber/dtype-next$ java --version\nopenjdk 11.0.12 2021-07-20\nOpenJDK Runtime Environment GraalVM CE 21.2.0 (build 11.0.12+6-jvmci-21.2-b08)\nOpenJDK 64-Bit Server VM GraalVM CE 21.2.0 (build 11.0.12+6-jvmci-21.2-b08, mixed mode, sharing)\n```\n\nThen run the code to generate the graalvm-specific bindings:\n\n```console\nclj -M -e \"(require 'avclj.gen-bindings)\"\n```\n\nNext you will need these system library packages:\n\n* libavcodec-dev\n* libavformat-dev\n* libswscale-dev\n* libavutil-dev\n* libx264-dev\n\n\nThen, after checking under generated_classes to be sure the class generation mechanism\nworked, simply run `scripts/compile`.\n\n* [gen_bindings.clj](native_test/avclj/gen_bindings.clj)\n* [main.clj](native_test/avclj/main.clj)\n\n\n### Graal Native Shared Library\n\nThis is using an experimental dtype-next API to export a set of functions from the uberjar to C.\n1. Same setup as above -- `gen_bindings` generates the bindings for the shared library.\n2.  Then run `scripts/compile-shared` to get a shared library written to the 'library' directory.  \n3.  Then in the 'library' directory, there is a script to compile a c++ executable against the shared library.  It encodes 300 frames or \nso - then decodes those frames.\n\nOne key lesson learned here is that your library export must only reference state that is also\nreferenced from the main class of the uberjar and the exported `defn`'s cannot have typehints.\n\n* [library export file](native_test/avclj/libavclj.clj)\n* [cpp encoder using referenced functions](library/testencode.cpp)\n\nYou have to export `LD_LIBRARY_PATH` to the library directory in order to load the shared\nlibrary.  But then, *hopefully*, you will get the right output:\n\n```console\n(base) chrisn@chrisn-lt3:~/dev/cnuernber/avclj/library$ export LD_LIBRARY_PATH=$(pwd)\n(base) chrisn@chrisn-lt3:~/dev/cnuernber/avclj/library$ ./compile.sh\n(base) chrisn@chrisn-lt3:~/dev/cnuernber/avclj/library$ ./a.out\ninitialized? 0\ninitialized? 1\n[libx264 @ 0x55f64aeb92c0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2\n[libx264 @ 0x55f64aeb92c0] profile High, level 2.1, 4:2:0, 8-bit\ngot encoder: 521232628\n[libx264 @ 0x55f64aeb92c0] frame I:2     Avg QP:13.06  size:  1014\n[libx264 @ 0x55f64aeb92c0] frame P:103   Avg QP:25.78  size:    88\n[libx264 @ 0x55f64aeb92c0] frame B:195   Avg QP:23.22  size:    87\n[libx264 @ 0x55f64aeb92c0] consecutive B-frames:  1.3% 36.0%  0.0% 62.7%\n[libx264 @ 0x55f64aeb92c0] mb I  I16..4: 50.2% 25.0% 24.8%\n[libx264 @ 0x55f64aeb92c0] mb P  I16..4:  1.2%  1.0%  1.0%  P16..4: 12.8%  0.3%  0.0%  0.0%  0.0%    skip:83.8%\n[libx264 @ 0x55f64aeb92c0] mb B  I16..4:  0.3%  0.0%  0.0%  B16..8: 32.9%  1.6%  0.0%  direct: 0.0%  skip:65.2%  L0:39.1% L1:60.9% BI: 0.0%\n[libx264 @ 0x55f64aeb92c0] 8x8 transform intra:26.4% inter:47.5%\n[libx264 @ 0x55f64aeb92c0] coded y,uvDC,uvAC intra: 6.7% 0.0% 0.0% inter: 0.0% 0.0% 0.0%\n[libx264 @ 0x55f64aeb92c0] i16 v,h,dc,p: 51% 35% 13%  0%\n[libx264 @ 0x55f64aeb92c0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 33%  7% 60%  0%  0%  0%  0%  0%  0%\n[libx264 @ 0x55f64aeb92c0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 39% 15% 45%  0%  0%  0%  0%  1%  0%\n[libx264 @ 0x55f64aeb92c0] i8c dc,h,v,p: 100%  0%  0%  0%\n[libx264 @ 0x55f64aeb92c0] Weighted P-Frames: Y:0.0% UV:0.0%\n[libx264 @ 0x55f64aeb92c0] ref P L0: 89.4%  0.9%  9.7%  0.0%\n[libx264 @ 0x55f64aeb92c0] ref B L0: 81.5% 18.1%  0.4%\n[libx264 @ 0x55f64aeb92c0] ref B L1: 99.2%  0.8%\n[libx264 @ 0x55f64aeb92c0] kb/s:44.84\nEncoded 300 frames.  Testing decode to RGB24\nDecoding frames 100x100\nJul 31, 2021 8:52:33 AM clojure.tools.logging$eval1$fn__4 invoke\nINFO: Reference thread starting\nDecoded 300 frames\n```\n\n\n## Extra Information\n \n* [Understanding Rate Control](https://slhck.info/video/2017/03/01/rate-control.html)\n* [FFmpeg H264 Encoding](https://trac.ffmpeg.org/wiki/Encode/H.264)\n\n## License - GPLv2\n\nFFmpeg provides a function to get the license of the library; it returns GPLv2 on my\nsystem. This library is thus transitively licensed under GPLv2.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcnuernber%2Favclj","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcnuernber%2Favclj","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcnuernber%2Favclj/lists"}