| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
camera: libcamfix substrate plugin + Camera.app photo delivery via CAMCaptureEngine libcamfix.dylib is loaded into Camera.app (com.apple.camera) by TweakLoader (the .app/-rule covers Camera.app automatically; the plist filters to Bundles=[com.apple.camera]). It bridges the vphone shm frames from libvcamcaptured into Camera.app's normal photo + preview pipeline so the user can take real photos via the standard shutter. Hooks (only fire for connections backed by AVCaptureDevice uid "vphone:vcam:0"): - _setActiveFormat: substitute device.formats.firstObject when the session-preset->format lookup hands us a nil format (would otherwise throw at launch). - capturePhoto deliver a CMSampleBuffer (built from shm) via the deprecated didFinishProcessingPhotoSample delegate path — kept for test harnesses that use the documented AVCapturePhotoOutput API. - beginMomentCapture / commitMomentCaptureToPhotoWithUniqueID: Camera.app's actual shutter path. Skip orig (would throw), stash the delegate at begin, drive a synthesized AVCapturePhoto at commit. - cancelMomentCaptureWithUniqueID: no-op (orig would throw). - AVCaptureSession _setRunning: / _setInterrupted: setters swallowed for vcam-bound sessions, and isRunning / isInterrupted getters force YES / NO so Camera.app's "preview live" poll keeps the viewfinder visible past ~4-5 s. - AVCaptureVideoPreviewLayer: scan UIApplication.windows at 1 Hz for layers bound to a vcam session and pump CGImage frames into layer.contents at 30 Hz. - AVCapturePhoto fileDataRepresentation / CGImageRepresentation: when the photo we synthesized is the receiver, return the JPEG / CGImage we built from shm instead of asking the (non-existent) photo surface to encode itself. - CAMStillImageCaptureRequest: dynamically add three stubs (resolvedSettings, unresolvedSettings, lensStabilizationSupported) so AVCapturePhoto's private 27-arg init does not throw on the CAM-internal request we pass in. Synthesized AVCapturePhoto construction: - extract the real CAMStillImageCaptureRequest for the current uid from CAMCaptureEngine._resultsQueueRegisteredStillImageRequests (Camera.app's pending-photo dict), - hand-build a minimal AVCaptureResolvedPhotoSettings via class_createInstance + ivar writes for uniqueID + dimensions + empty NSArray ivars (CFRetained so the dealloc chain stays valid), - feed both into AVCapturePhoto's documented 27-arg initWithTimestamp:photoSurface:... via NSInvocation, - tag the photo with the JPEG bytes via objc_setAssociatedObject so the fileDataRepresentation hook returns them. Full AVF + CAM internal delegate sequence fired at commit time: willBeginCaptureBeforeResolvingSettingsForUniqueID, willBeginCaptureForResolvedSettings, willCapturePhotoForResolvedSettings, didCapturePhotoForResolvedSettings, didFinishProcessingPhoto:error:, didFinishCaptureForResolvedSettings:error:, _didFinishStillImageCaptureForUniqueID:error:, and crucially captureOutput:readyForResponsiveRequestAfterResolvedSettings:. Without that last "responsive ready" signal AVF's 2-deep pipeline never frees its slots and Camera.app's shutter stops accepting input after the 2nd capture. Install wiring in scripts/cfw_install_exp.sh: - build_libcamfix() — clang -arch arm64e -fobjc-arc -Os, frameworks AVFoundation / CoreImage / CoreMedia / CoreVideo / Foundation / ImageIO / IOSurface / MobileCoreServices / Photos / QuartzCore / UIKit, ldid-signed. - [JB-4.2] scp the dylib + plist into procursus/Library/MobileSubstrate/ DynamicLibraries (same location as libvcamcaptured) and chmod / chown so TweakLoader picks them up on next boot. End state: Camera.app on EXP shows live preview from the host-supplied vcam frames, the shutter takes real photos that get saved into Photos via Camera.app's own pipeline (no PHPhotoLibrary back-channel), and the shutter button keeps working across many consecutive captures. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> | 2 个月前 | |
camera: discover AVCapturePhoto + resolvedSettings selectors at runtime Replace the two giant hardcoded selectors (the 27-arg AVCapturePhoto init and the 32-arg +resolvedSettingsWithUniqueID:… factory) with a prefix-lookup + label-driven NSInvocation builder. This survives Apple adding or removing args between iOS releases without code changes: the discovered selector decides arg count and order, the resolver block fills the args we care about by label ("timestamp", "photoSurface", "uniqueID", "photoDimensions", etc.), and unknown labels get nil/zero from the runtime type encoding. cfx_find_selector_by_prefix(cls, prefix, classMethod) Walks class_copyMethodList on cls (or its metaclass for class methods), returns the matching selector with the most colons. Highest-arg-count match wins so a future Apple revision that adds a new arg in the middle is still found. cfx_normalize_first_label(NSString *) Strips "initWith" / "resolvedSettingsWith" and lowercases the first char of the remainder so the leading component matches the same label convention as the rest of the selector. cfx_invoke_with_labeled_args(target, selector, resolver) Builds the NSInvocation, iterates selector components, calls the resolver block once per arg with (label, typeEnc, outBuf). Block writes the value via the appropriate cast (CMTime, IOSurfaceRef, __unsafe_unretained id, NSInteger, etc.) or leaves outBuf zeroed. Builders refactored: - cfx_build_resolved_settings now fills only uniqueID + photoDimensions + previewDimensions; everything else stays zero/nil (Apple's impl tolerates that on builds where the factory itself works at all). - cfx_build_avcapturephoto_with_request fills timestamp, photoSurface, photoSurfaceSize, processedFileType, metadata, captureRequest, sequenceCount, photoCount, sourceDeviceType. Every other surface/dictionary arg defaults to nil. End state: net +169/-96 lines, zero hardcoded full selectors, photo synthesis remains functionally identical on 26.5 and is prepared for arg-list drift on future iOS revisions. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> | 2 个月前 | |
camera: load libcamfix into every AVFoundation client via TweakLoader Filter.Frameworks Universal injection mechanism: any process where AVFoundation is loaded (Camera.app, continuitycaptured, third-party apps, system daemons — anything dyld pulls AVF into) automatically gets libcamfix via TweakLoader. No per-bundle plist filter, no allowlist entries. scripts/tweakloader/TweakLoader.m New Filter.Frameworks key. A tweak's plist may list framework names; TweakLoader matches the path containing "/<name>.framework/". Already-loaded frameworks trigger an immediate dlopen; not-yet-loaded frameworks register a _dyld_register_func_for_add_image callback that fires when the named framework appears. Two-tier engagement: - Framework-filtered tweaks scan + schedule in EVERY process, self-limiting at runtime. Cost in non-AVF processes is one dir scan + a few plist parses + one callback registration. - Non-framework tweaks (Bundles/Executables or no filter) keep the existing .app/+kVPhoneAllowedDaemonPaths gate so we don't drop arbitrary tweaks into launch-critical daemons. CRITICAL safety: dyld invokes add-image callbacks SYNCHRONOUSLY inside its loader lock. dlopen from within that callback recurses and can deadlock or crash early daemons. The actual dlopen is handed off to a background queue (dispatch_async) so it runs after dyld is idle. Defensive: each per-tweak block is @try/@catch wrapped so a malformed plist or Foundation quirk in an early-boot daemon can't crash the process and trigger a launchd respawn loop. scripts/camfix/libcamfix.m Constructor no longer eagerly installs hooks. Instead registers a _dyld_register_func_for_add_image callback and installs hooks the first time AVFCapture's mach header is observed (idempotent via dispatch_once). Whether libcamfix loads before or after AVFCapture, hooks land exactly once. cfx_capturePhoto_hook now drives the MODERN -[<AVCapturePhotoCaptureDelegate> captureOutput: didFinishProcessingPhoto:error:] path in addition to the deprecated CMSampleBuffer one. The synthesized AVCapturePhoto uses nil captureRequest (there's no CAMCaptureEngine outside Camera.app — msgSend to nil during init returns 0 safely). Photos tagged with associated JPEG/CGImage so fileDataRepresentation / CGImageRepresentation return our bytes regardless of which delegate protocol the client implements. scripts/camfix/libcamfix.plist Filter.Frameworks = ["AVFoundation"]. Replaces the previous Bundles=["com.apple.camera"] filter. scripts/cfw_install_exp.sh build_libcamfix install_name reverted to /var/jb/Library/ MobileSubstrate/DynamicLibraries/libcamfix.dylib (TweakLoader location). [JB-4.2] deploys dylib + plist together. Verified on fresh `make setup_machine` install of 26.5: - 373+ distinct AVF-using processes auto-load libcamfix at boot, including watchdogd / amfid / backboardd / SpringBoard / cameracaptured / continuitycaptured. - Camera.app: preview live, photos save, shutter works past many consecutive captures. - continuitycaptured: a vanilla AVCapturePhotoCaptureDelegate using the documented capturePhotoWithSettings:delegate: API gets a real 1280x720 JFIF JPEG via the modern delegate path. - Full reboot cycle stable. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> | 2 个月前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 |