EyeQ Docs

Video Processing

Real-time video processing on iOS with camera preview and deflickering

This guide covers real-time video processing on iOS, including camera preview with AVCaptureSession and deflickering configuration.

Understanding deflickering

When processing video frames, the correction applied to each frame can vary based on the frame's content. Without temporal smoothing, this causes visible flickering between frames.

The SDK provides deflickering parameters that smooth corrections across frames:

ParameterDescriptionRecommended
deflickerCurveSmooths tone curve adjustments (0.0–1.0)0.08
deflickerImageSmooths overall corrections (0.0–1.0)0.9
skipProcess every Nth frame (0 = all)0–1

Deflickering has a cumulative effect. Call resetDeflicker() when switching cameras, starting a new video, or seeking to a different position.

Camera preview with AVCaptureSession

Process live camera frames using AVCaptureSession:

class CameraViewController: UIViewController {

    private let pfcDynamic: PFCDynamic
    private let session = AVCaptureSession()
    private let videoOutput = AVCaptureVideoDataOutput()
    private let videoQueue = DispatchQueue(label: "video.processing")

    private var previewImageView: UIImageView!
    private var dynamicStrength: Float = 0.8

    init(apiKey: String, certificate: String) {
        self.pfcDynamic = PFCDynamic(apiKey: apiKey, certificate: certificate)
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Verify initialization
        let status = pfcDynamic.checkStatus()
        if status != 0 {
            print("SDK initialization failed with code: \(status)")
            return
        }

        // Configure deflickering for video
        pfcDynamic.setParams(
            deflickerCurve: 0.08,
            deflickerImage: 0.9,
            skip: 0
        )

        setupCamera()
    }

    @objc func switchCamera() {
        // Reset deflicker when switching cameras
        pfcDynamic.resetDeflicker()

        // Switch camera logic...
    }
}

extension CameraViewController: AVCaptureVideoDataOutputSampleBufferDelegate {

    func captureOutput(
        _ output: AVCaptureOutput,
        didOutput sampleBuffer: CMSampleBuffer,
        from connection: AVCaptureConnection
    ) {
        guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer),
              let cgImage = createCGImage(from: imageBuffer) else { return }

        do {
            let processed = try pfcDynamic.processImage(
                cgImage,
                strength: dynamicStrength
            )

            let image = UIImage(cgImage: processed)

            DispatchQueue.main.async {
                self.previewImageView.image = image
            }
        } catch {
            print("Frame processing error: \(error)")
        }
    }

    private func createCGImage(from imageBuffer: CVImageBuffer) -> CGImage? {
        let ciImage = CIImage(cvImageBuffer: imageBuffer)
        let context = CIContext()
        return context.createCGImage(ciImage, from: ciImage.extent)
    }

    private func setupCamera() {
        // AVCaptureSession setup code here
    }
}

Frame skipping for performance

Use the skip parameter to reduce processing load:

// Process all frames (highest quality, most CPU)
pfcDynamic.setParams(deflickerCurve: 0.08, deflickerImage: 0.9, skip: 0)

// Skip every other frame (good balance)
pfcDynamic.setParams(deflickerCurve: 0.08, deflickerImage: 0.9, skip: 1)

// Skip 2 frames between processed frames (performance mode)
pfcDynamic.setParams(deflickerCurve: 0.08, deflickerImage: 0.9, skip: 2)

When skipping frames, the SDK reuses the previous frame's correction for skipped frames, maintaining visual consistency.

When to reset deflicker

Always call resetDeflicker() in these situations:

ScenarioAction
Switch camera (front/back)Call resetDeflicker()
Start new video recordingCall resetDeflicker()
Seek in video playerCall resetDeflicker()
Load new video fileCall resetDeflicker()
Resume from backgroundCall resetDeflicker()

VIDEO-SDK Version 1.0.0.23 built from aa5eef97017e23db1d3051b079500606825ef474 on 5-6-2023.

Copyright © 2026 EyeQ Imaging Inc. All rights reserved.

On this page