9 Commits

Author SHA1 Message Date
marfrit df339c07fd Install daedalus-decoder.pc for sibling consumers
Adds pkg-config plumbing so consumers (daedalus-v4l2 daemon for the
upcoming PR-Q3a shadow-mode wiring; the daedalus_decode_h264 CLI when
built outside this tree) can locate libdaedalus_decoder.a + the public
header via pkg_check_modules / pkg-config.

Mirrors daedalus-fourier's relocatable-prefix scheme: prefix is derived
from ${pcfiledir} so cmake --install --prefix /foo produces a .pc that
resolves to /foo at lookup time. Verified across two install prefixes.

daedalus-fourier is declared as a public Requires: because consumers
static-linking libdaedalus_decoder.a also need libdaedalus_core.a in
their link line to resolve the daedalus_ctx_* / daedalus_recipe_*
symbols this archive references.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 13:32:58 +02:00
marfrit 9061350e82 Merge pull request 'PR-A6: enable libavcodec deblock + drive daedalus deblock on real streams' (#16) from noether/tools-h264-deblock-validation into main
Reviewed-on: #16
2026-05-26 10:12:30 +00:00
claude-noether b597fc0098 PR-A6: enable libavcodec deblock + drive daedalus deblock on real streams
PARTIAL PASS — full I-frame pipeline (IDCT + deblock) running on real
H.264 streams via daedalus-decoder's frame-major dispatch.  Residual
divergence vs libavcodec reference: 0.09% to 0.86% Y / 0.35% to 2.0%
UV depending on substrate + resolution.  Kernel-level off-by-one
issues remain; structurally same family as task #179.

Architecture (verified against `dejavu` memory before coding)
-------------------------------------------------------------

  - NO new libavcodec patches.  Uses existing 0016 + 0017 callback
    infrastructure.
  - daedalus-decoder is the consumer-side frame-major dispatch path;
    libavcodec runs to produce the post-deblock reference.  Daedalus
    is NOT substituted into libavcodec's deblock path.
  - Edge derivation is a one-time spec implementation in the CLI, not
    a per-block function-pointer hijack.

Different shape from the banned per-kernel substitution arc.  Hard
re-check vs the magic word memory before any tool call (per the user's
explicit instruction "make sure no dejavu").

What changed in the CLI
-----------------------

  1. avctx->skip_loop_filter dropped — libavcodec's deblock now runs
     and AVFrame is post-deblock (the new reference).
  2. Per-MB callback captures pre-deblock pixels for all 3 planes
     (Y/Cb/Cr) at MB(N)'s own callback time — pure pre-deblock for
     MB(N) regardless of incremental deblock timing for neighbours
     (filter_mb runs AFTER hl_decode_mb returns, so callback sees
     fresh-decoded fresh-pre-deblock pixels).
  3. Per-MB callback also captures qp_y, mb_type_intra,
     transform_8x8.  Slice-level: slice_alpha_c0_offset,
     slice_beta_offset, slice_deblocking_filter.
  4. Transcribed H.264 §8.7.2 alpha_table[156], beta_table[156],
     tc0_table[156][4] from FFmpeg's h264_loopfilter.c (LGPL-2.1+
     transcription; algorithm/values normative-spec, unpatented).
  5. Transcribed §8.5.11 / Table 8-11 chroma_qp_table[52] for
     qP_Y → qP_C conversion (chroma_qp_index_offset assumed 0,
     which matches x264 default).
  6. Main loop: for each MB, build daedalus_decoder_mb_input.edges
     from spec rules.  16 edges/MB (4 V-luma + 4 H-luma + 2 V-Cb +
     2 V-Cr + 2 H-Cb + 2 H-Cr).  bS=4 at MB boundary, bS=3 internal,
     bS=0 at frame boundary.  8x8 DCT MBs skip internal edges at
     col/row 4 and 12 (only the 8x8-block boundary fires).
  7. Daedalus's flush_frame runs IDCT-add for real-coeffs MBs +
     identity passthrough for skipped MBs, THEN dispatches the 4
     deblock kernels (luma V/H + chroma V/H, plus their bS=4 intra
     variants) across the frame.
  8. Compare daedalus output to AVFrame (post-deblock).

Subtle bug hunted: sl->deblocking_filter convention inversion
-------------------------------------------------------------

FFmpeg's h264_slice.c line 1901 does `sl->deblocking_filter ^= 1`
to invert the spec's `disable_deblocking_filter_idc` semantics.
Internal convention:
  - 0 = DISABLED (was 1 in spec)
  - 1 = ENABLED  (was 0 in spec)
  - 2 = enabled-but-not-across-slice-boundaries (unchanged)

Initial implementation treated `== 1` as "disabled" per spec
semantics, which silently skipped all edge emission (deblock_off=1)
and gave the same diff count as the no-edges baseline.  Inverted
to `deblock_off = (sl->deblocking_filter == 0)`; edges then flowed
and divergence dropped 5346→438 Y diffs (92% reduction) per frame.

Results on hertz (Pi 5 V3D 7.1)
-------------------------------

testsrc2 I-only via libx264 -bf 0 -g 1:

  320×240, 5 frames, substrate=cpu:
    Y diff 2009/384000 (0.52%), UV diff 3876/192000 (2.02%)
  320×240, 5 frames, substrate=qpu:
    Y diff 3288/384000 (0.86%), UV diff 3577/192000 (1.86%)
  1920×1088, 3 frames, substrate=auto:
    Y diff 5810/6266880 (0.09%), UV diff 10921/3133440 (0.35%)

The 1080p rate is lower than QVGA's — content has fewer edges relative
to total pixels at higher resolution.

Residual divergence — root cause analysis
-----------------------------------------

  - CPU substrate uses ff_h264_*_loop_filter_*_neon (same kernel
    libavcodec uses).  Same kernel + same alpha/beta/tc0/bS → output
    SHOULD be identical.  But still 0.52% Y diff.
  - Likely cause: edge dispatch ORDER mismatch.  libavcodec serialises
    per-MB (filter MB(N)'s edges, then MB(N+1)'s).  Daedalus batches
    frame-wide (all V luma across the frame, then all H luma, etc.).
    For overlapping-pixel zones (e.g., MB(N)'s col 12 internal edge
    + MB(N+1)'s col 0 boundary edge both touch cols 13-15), the
    order affects the final pixel.
  - QPU substrate has slightly higher divergence (0.86% Y) — additional
    kernel-level off-by-one between daedalus's V3D shader and the NEON
    reference, in the same family as task #179's chroma divergence.

These are kernel-level / dispatch-order issues, not CLI bugs.  Task #179
extended in scope (now includes luma + cross-MB edge ordering); root
cause investigation belongs in daedalus-fourier.

PR-A6 verifies the INFRASTRUCTURE: real coefficients flow through, real
edges are derived per spec, daedalus runs IDCT + deblock in one frame-
major dispatch, output is within ~1% of libavcodec reference on real
H.264 streams.  Full byte-exact closure depends on the daedalus-fourier
deblock kernel/dispatch investigation.

Followups
---------

  - Extend task #179 to cover luma edges + cross-MB edge ordering on
    real-stream layouts.
  - PR-A4: Intra_16x16 + chroma DC Hadamard.  Would also help the UV
    diff rate since currently chroma is identity-passthrough (no real
    chroma residual coefficients flowing through daedalus).
  - Q3 deferred: daemon refactor in daedalus-v4l2.
2026-05-26 11:53:23 +02:00
marfrit 35b4f163c6 Merge pull request 'Stage 2 PR-A3b: real H.264 coefficients through daedalus-decoder, byte-exact' (#15) from noether/tools-h264-real-coeffs into main
Reviewed-on: #15
2026-05-26 09:36:03 +00:00
claude-noether 44e92fa3dc Stage 2 PR-A3b: real H.264 coefficients through daedalus-decoder, byte-exact
Final option-A deliverable.  CLI now extracts real per-MB
coefficients from libavcodec via the inspection callback +
side-buffer (marfrit-packages 0016 + 0017), reconstructs the
pre-residual predicted samples P via inverse-of-IDCT-add, and
feeds daedalus-decoder with real (P, C, no edges).  Daedalus
output BYTE-EXACT against libavcodec's pre-deblock AVFrame
across 5 frames at 320x240 and 3 frames at 1920x1088, all three
substrates (auto / cpu / qpu).

Path summary
------------

avctx->thread_count = 1                  (single-threaded decode — 0017's
                                           side buffer is per-H264Context;
                                           multi-threaded would race)
avctx->skip_loop_filter = AVDISCARD_ALL  (AVFrame stays pre-deblock so the
                                           P-recovery subtraction is exact)
ff_h264_set_mb_inspect_cb               (registers the callback)

Inspection callback (per MB, fires post-hl_decode_mb):
  - Gate on IS_INTRA4x4 && !IS_8x8DCT && !IS_INTRA_PCM (skipped MBs
    fall back to identity-passthrough in the main loop)
  - Snapshot pre-deblock pixels from h->cur_pic.f->data[0]
  - Read coefficients from h->mb_inspect_coeffs (= sl->mb copy, the
    0017 side buffer)
  - For each 4x4 block (16/MB in raster order, indexed via
    raster_to_zscan[] to find its slot in the z-scan-ordered side
    buffer): compute IDCT(C) using a transcribed H.264 C reference,
    derive P = clip(pre_deblock - ((IDCT + 32) >> 6))
  - Stash per-MB capture (P + C) for the main loop

Main loop:
  - Default identity-passthrough (predicted = AVFrame pixels, coeffs = 0)
  - For real-coeffs-valid MBs: override luma with captured P + C
  - flush_frame, byte-exact compare against AVFrame

A diagnostic also asserts (silently when passing) that the
callback's pre_deblock snapshot equals AVFrame at each real-coeffs
MB position — i.e. h->cur_pic.f IS the eventual AVFrame buffer
under skip_loop_filter=AVDISCARD_ALL with thread_count=1.

Bug hunted in this PR
---------------------

Initial implementation transposed the coefficients from row-major
(sl->mb) to "column-major" (the layout that daedalus_decoder.h's
mb_input.coeffs docstring describes).  This caused ~0.2% Y pixel
divergence on real streams (~150/frame at 320x240).  Root cause
identified via a standalone /tmp/idct_compare.c harness running
daedalus's C ref IDCT and FFmpeg's reference C IDCT on identical
int16[16] inputs: outputs IDENTICAL.  The two functions implement
the spec H.264 IDCT on the array regardless of layout
interpretation; the "column-major" label is decoration.  Removed
the transpose; PR is now byte-exact.

Follow-up task #184: clarify daedalus_decoder.h's mb_input.coeffs
docstring so future integrators don't repeat this transpose
mistake.

Result on hertz (Pi 5 V3D 7.1)
------------------------------

testsrc2 I-only via libx264 -bf 0 -g 1:

  320x240,    5 frames, substrate=auto:  Y diff 0/76800,    UV diff 0/38400   PASS
  320x240,    5 frames, substrate=cpu:   Y diff 0/76800,    UV diff 0/38400   PASS
  320x240,    5 frames, substrate=qpu:   Y diff 0/76800,    UV diff 0/38400   PASS
  1920x1088,  3 frames, substrate=auto:  Y diff 0/2088960,  UV diff 0/1044480 PASS

Real-coeffs path engaged for 77-95 MBs per 320x240 frame and
598-643 MBs per 1080p frame (testsrc2 is mostly flat → many
Intra_16x16 MBs that fall back to identity passthrough; richer
content streams would engage real-coeffs more).

Followups
---------

  - PR-A4: extend the gate to Intra_16x16 (chroma DC Hadamard +
    Intra_16x16 luma DC Hadamard pre-pass) — currently ~30-60%
    of MBs fall back to identity-passthrough due to this.
  - PR-A5: extend to 8x8 transform (separate IDCT 8x8 dispatch
    path on the daedalus-decoder side, similar plumbing).
  - PR-A6: enable libavcodec's deblock (skip_loop_filter=AVDISCARD_NONE)
    and have daedalus's deblock produce the post-deblock output
    that matches AVFrame.  Closes the loop on the full I-only
    pipeline.
  - Task #184: daedalus_decoder.h coeffs docstring clarification.
2026-05-26 11:19:11 +02:00
marfrit 69d68e0323 Merge pull request 'Stage 2 PR-A2: per-MB inspection callback wiring + invariant checks' (#14) from noether/tools-h264-callback-wiring into main
Reviewed-on: #14
2026-05-26 07:06:39 +00:00
claude-noether 86a28d2a3b Stage 2 PR-A2: per-MB inspection callback wiring + invariant checks
Validates marfrit-packages patch 0016 (PR #106) end-to-end against
the daedalus_decode_h264 CLI.  Callback fires once per macroblock
in coded order; this PR checks the count + uniqueness invariants
WITHOUT yet driving daedalus-decoder differently — that's PR-A3.

Infrastructure landed
---------------------

CMake gains DAEDALUS_FFMPEG_PREFIX option pointing at a private
FFmpeg install carrying patch 0016.  When set, the CLI links
against it (static .a's from $prefix/lib) and the inspection
codepath is compiled in (DAEDALUS_HAVE_H264_MB_INSPECT_CB).  When
unset, the CLI falls back to the pkg-config-discovered system
FFmpeg and behaves as PR-A1b did (identity-passthrough only, no
callback).

The H264Context struct stays opaque (forward-decl only — its
real definition lives in libavcodec's internal h264dec.h which
isn't installed).  Real per-MB state extraction (sl->mb coeffs,
mb_type, intra modes, deblock params) will land in PR-A3
alongside an internal-header include path.

The callback's only job in this PR: assert (mb_x, mb_y) lies in
the coded grid, mark "seen" in a per-frame bitmap, count
invocations.  At end-of-frame: assert seen-count == mb_w*mb_h,
0 duplicates, 0 out-of-bounds.

Per-frame mb-grid init goes BEFORE first avcodec_send_packet
(callbacks fire from inside send_packet, before the first
receive_frame ever returns — lazy init from AVFrame would miss
all of frame 0).  Dims come from codecpar->width/height rounded
up to 16-mod (H.264 codes 1080 display as 1088 coded).

Raster-order check considered but dropped: libavcodec uses
MB-level threading in some configs so callbacks fire out of
raster order.  The contract is "each MB exactly once", not "in
raster order"; the bitmap check captures that.

Result on hertz (Pi 5, patched FFmpeg at /tmp/ffmpeg-inspect-prefix)
-------------------------------------------------------------------

  320x240 I-only, 3 frames:
    mb-grid 20x15
    callback invocations: 900 (= 3 * 300)
    missing/duplicates/oob: 0/0/0
    identity-passthrough Y diff 0/230400, UV diff 0/115200
    PASS

  1920x1088 I-only, 3 frames:
    mb-grid 120x68
    callback invocations: 24480 (= 3 * 8160)
    missing/duplicates/oob: 0/0/0
    identity-passthrough Y diff 0/6266880, UV diff 0/3133440
    PASS

Followups
---------

  - PR-A3: include libavcodec/h264dec.h via -I to access H264Context
    internals; extract sl->mb coefficients in the callback, compute
    P = pre-deblock pixels - IDCT(C) using a transcribed C reference;
    feed daedalus_decoder with REAL (P, C, edges) instead of identity.
    Use avctx->skip_loop_filter = AVDISCARD_ALL to make libavcodec
    output pre-deblock so the subtraction is exact.
  - PR-A4 onwards: extend to P/B frames + chroma DC + intra prediction
    coverage.
2026-05-26 07:06:31 +02:00
marfrit 972a79dde2 Merge pull request 'Stage 2 PR-A1b: tools/daedalus_decode_h264 — H.264 standalone test harness' (#13) from noether/tools-h264-cli into main
Reviewed-on: #13
2026-05-26 04:55:42 +00:00
claude-noether 56f8498057 Stage 2 PR-A1b: tools/daedalus_decode_h264 — H.264 standalone test harness
Option A's standalone end-to-end gate against real H.264 streams.
First iteration: identity-passthrough validation — daedalus-decoder
produces output byte-exact to libavcodec's AVFrame when fed the
reconstructed pixels as `predicted`, zero coeffs, no deblock edges.

Validates: daedalus-decoder data path (append_mb + flush_frame +
NV12 output + coded-vs-display dim handling) at real-stream frame
sizes (320x240 and 1920x1088) with real H.264-decoded predicted-
sample distributions — not the random patterns the existing
test_idct_bitexact + test_deblock_smoke synthesize.

Identity-passthrough math:
  - mb_input.predicted = AVFrame pixels at MB raster position
  - mb_input.coeffs    = 384 int16's, all zero
  - mb_input.edges     = NULL, n_edges = 0
  flush_frame:
    scratch_y/_uv pre-fill from predicted (= AVFrame pixels)
    IDCT dispatches with all-zero coeffs add 0 (no-op compute)
    No deblock dispatches (no edges)
    copy-out → caller's NV12 planes
  Result MUST equal AVFrame pixels byte-for-byte.

Build
-----

New cmake option DAEDALUS_BUILD_TOOLS (default OFF).  When enabled,
pkg-checks libavcodec / libavformat / libavutil and builds the
daedalus_decode_h264 binary against the system FFmpeg.

Stock libavcodec is sufficient for THIS PR (identity passthrough
reads from AVFrame after avcodec_receive_frame; no per-MB internal
state extraction needed).  Follow-up PRs (A2+) will use the per-MB
inspection callback added in marfrit-packages patch 0016 (PR #106)
to feed REAL per-MB state (pre-residual predicted samples, residual
coeffs, deblock edges) for actual non-trivial daedalus-decoder
validation.

Usage
-----

  daedalus_decode_h264 [--substrate cpu|qpu|auto]
                       [--max-frames N]
                       <input.h264> <output_dadec.yuv> <output_ref.yuv>

Exit codes:
  0 = byte-exact match across all frames
  1 = argument / setup error
  2 = decode error from libavcodec
  3 = daedalus-decoder error (ctx, append, flush)
  4 = bit-exact comparison failed

Result on hertz (Pi 5 V3D 7.1)
------------------------------

I-only test clip via ffmpeg testsrc2 + libx264 -bf 0 -g 1:

  320x240, 5 frames:
    substrate=auto:  Y diff 0/76800   UV diff 0/38400   PASS
    substrate=cpu:   Y diff 0/76800   UV diff 0/38400   PASS
    substrate=qpu:   Y diff 0/76800   UV diff 0/38400   PASS

  1920x1088 (coded; 1080 display), 3 frames:
    substrate=auto:  Y diff 0/2088960 UV diff 0/1044480 PASS

Followups
---------

  - PR-A2: wire the per-MB inspection callback (marfrit-packages
    0016) so per-MB state — coeffs (sl->mb), predicted-before-
    residual (from prediction kernels), bS/alpha/beta — flows into
    mb_input instead of zeros, and IDCT / deblock dispatches do
    real GPU work.  At that point we're decoding real H.264 streams
    through daedalus-decoder for real.
  - PR-A3: extend to P/B frames once MC dispatch lands.
2026-05-26 06:12:51 +02:00
2 changed files with 1133 additions and 3 deletions
+112 -3
View File
@@ -162,14 +162,123 @@ add_executable(bench_flush_frame tests/bench_flush_frame.c)
target_link_libraries(bench_flush_frame PRIVATE daedalus_decoder)
target_compile_options(bench_flush_frame PRIVATE -O2)
# ---- Tools (not gated by ctest; opt-in via DAEDALUS_BUILD_TOOLS) ----
#
# daedalus_decode_h264 — option A standalone test harness that
# wraps libavcodec + daedalus-decoder and bit-exact-compares their
# outputs on real H.264 streams. Identity-passthrough mode in this
# first iteration (predicted = AVFrame pixels, coeffs = 0, no
# deblock edges); follow-up PRs use the per-MB inspection callback
# (marfrit-packages patch 0016) to feed REAL per-MB state.
#
# Requires libavcodec + libavformat headers + libs. Off by default
# so the standard ctest build doesn't pull in FFmpeg as a hard dep.
option(DAEDALUS_BUILD_TOOLS "Build daedalus-decoder CLI tools (requires libavcodec)" OFF)
if(DAEDALUS_BUILD_TOOLS)
# Optional path to a private FFmpeg install carrying the per-MB
# inspection callback (marfrit-packages patch 0016). When set,
# the CLI links against it instead of the system FFmpeg and the
# inspection-callback code path is compiled in.
set(DAEDALUS_FFMPEG_PREFIX "" CACHE PATH
"Path to a patched FFmpeg install (with 0016 mb-inspect-callback) for daedalus_decode_h264. Empty = use system pkg-config FFmpeg.")
if(DAEDALUS_FFMPEG_PREFIX)
message(STATUS "daedalus_decode_h264: patched FFmpeg at ${DAEDALUS_FFMPEG_PREFIX}")
set(FFMPEG_INCLUDE_DIRS ${DAEDALUS_FFMPEG_PREFIX}/include)
set(FFMPEG_LIBRARY_DIRS ${DAEDALUS_FFMPEG_PREFIX}/lib)
# Patched libavcodec is built static (no shared libs in the private prefix).
# System pull-ins are still needed for libav* dependencies.
set(FFMPEG_LIBRARIES
${DAEDALUS_FFMPEG_PREFIX}/lib/libavformat.a
${DAEDALUS_FFMPEG_PREFIX}/lib/libavcodec.a
${DAEDALUS_FFMPEG_PREFIX}/lib/libavutil.a
${DAEDALUS_FFMPEG_PREFIX}/lib/libswresample.a
m z pthread)
set(FFMPEG_CFLAGS_OTHER "-DDAEDALUS_HAVE_H264_MB_INSPECT_CB=1")
# PR-A3+ optional: also point at the patched FFmpeg SOURCE TREE
# so the CLI can include libavcodec/h264dec.h directly and
# dereference H264Context fields (the side-buffer mb_inspect_coeffs
# added in marfrit-packages patch 0017, the cur_pic.f for
# pre-deblock pixel access, etc.). When set, the internal-header
# include codepath is compiled in.
set(DAEDALUS_FFMPEG_SRC "" CACHE PATH
"Path to patched FFmpeg source tree (= path to FFmpeg/ checkout where build was run; contains config.h + libavcodec/h264dec.h). Empty = h264dec.h includes are disabled.")
if(DAEDALUS_FFMPEG_SRC)
message(STATUS "daedalus_decode_h264: FFmpeg source at ${DAEDALUS_FFMPEG_SRC}")
# IMPORTANT: source tree FIRST in -I order — its
# libavutil/common.h does #include "intmath.h" with HAVE_AV_CONFIG_H,
# which resolves to libavutil/intmath.h (in the source tree
# only — that header isn't installed since it's arch-dispatched).
# The installed-prefix include path's libavutil/common.h is the
# same file textually but resolves "intmath.h" against the
# install dir where it doesn't exist.
set(FFMPEG_INCLUDE_DIRS ${DAEDALUS_FFMPEG_SRC})
set(FFMPEG_CFLAGS_OTHER
"${FFMPEG_CFLAGS_OTHER} -DDAEDALUS_HAVE_H264_MB_INSPECT_COEFFS=1 -DHAVE_AV_CONFIG_H")
# Convert space-separated string to list (CMake idiom for compile flags).
separate_arguments(FFMPEG_CFLAGS_OTHER UNIX_COMMAND "${FFMPEG_CFLAGS_OTHER}")
endif()
else()
pkg_check_modules(FFMPEG REQUIRED libavcodec libavformat libavutil)
message(STATUS "daedalus_decode_h264: system FFmpeg (no inspection callback)")
endif()
add_executable(daedalus_decode_h264 tools/daedalus_decode_h264.c)
target_link_libraries(daedalus_decode_h264
PRIVATE daedalus_decoder ${FFMPEG_LIBRARIES})
target_include_directories(daedalus_decode_h264
PRIVATE ${FFMPEG_INCLUDE_DIRS})
target_link_directories(daedalus_decode_h264
PRIVATE ${FFMPEG_LIBRARY_DIRS})
target_compile_options(daedalus_decode_h264
PRIVATE -O2 ${FFMPEG_CFLAGS_OTHER})
endif()
# ---- Install ------------------------------------------------------
#
# Library + public header. Stage 2/3 will add a pkg-config file and
# CMake config exports once the API stabilises; pre-0.1 the scaffold
# install just gives the static archive a home.
# Installs:
# - libdaedalus_decoder.a → ${CMAKE_INSTALL_LIBDIR}
# - include/daedalus_decoder.h → ${CMAKE_INSTALL_INCLUDEDIR}
# - daedalus-decoder.pc → ${CMAKE_INSTALL_LIBDIR}/pkgconfig
#
# The .pc lets sibling consumers (daedalus-v4l2 daemon, the
# daedalus_decode_h264 CLI when built externally) discover the static
# archive + headers via pkg-config. daedalus-fourier is declared as a
# public `Requires:` because the consumer (which static-links
# libdaedalus_decoder.a) also needs daedalus-fourier in its own link
# line to resolve the daedalus_ctx_* / daedalus_recipe_* symbols this
# archive references.
#
# Relocatable-prefix scheme mirrors daedalus-fourier's .pc generation:
# `prefix` is derived from ${pcfiledir} so `cmake --install --prefix /foo`
# produces a .pc that resolves prefix=/foo at lookup time, regardless of
# what CMAKE_INSTALL_PREFIX was at configure time.
include(GNUInstallDirs)
install(TARGETS daedalus_decoder
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES include/daedalus_decoder.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
file(RELATIVE_PATH PKGCONFIG_PCDIR_TO_PREFIX
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/pkgconfig"
"${CMAKE_INSTALL_PREFIX}")
set(PKGCONFIG_OUT ${CMAKE_CURRENT_BINARY_DIR}/daedalus-decoder.pc)
file(WRITE ${PKGCONFIG_OUT}
"prefix=\${pcfiledir}/${PKGCONFIG_PCDIR_TO_PREFIX}
exec_prefix=\${prefix}
libdir=\${prefix}/${CMAKE_INSTALL_LIBDIR}
includedir=\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}
Name: daedalus-decoder
Description: Frame-major H.264 decoder on V3D7 via daedalus-fourier primitives
Version: ${PROJECT_VERSION}
Libs: -L\${libdir} -ldaedalus_decoder
Requires: daedalus-fourier
Cflags: -I\${includedir}
")
install(FILES ${PKGCONFIG_OUT}
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
)
File diff suppressed because it is too large Load Diff