Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IOSurface and Documentation Update #2

Merged
merged 1 commit into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Test Swift Package

on:
pull_request:
branches: [main]

jobs:
test:
runs-on: macos-latest

steps:
- uses: actions/checkout@v3
- uses: swift-actions/setup-swift@v2
with:
swift-version: '5.9'

- name: Build
run: swift build

- name: Run Tests
run: swift test
5 changes: 5 additions & 0 deletions .spi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
version: 1
builder:
configs:
- documentation_targets: [CoreVideoTools]
scheme: CoreVideoTools
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2022 Eugene Bokhan
Copyright (c) 2024 Eugene Bokhan

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
10 changes: 7 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// swift-tools-version: 5.4
// swift-tools-version: 5.9

import PackageDescription

let package = Package(
name: "core-video-tools",
platforms: [
.iOS(.v11),
.iOS(.v12),
.macOS(.v10_13)
],
products: [
Expand All @@ -15,6 +15,10 @@ let package = Package(
)
],
targets: [
.target(name: "CoreVideoTools")
.target(name: "CoreVideoTools"),
.testTarget(
name: "CoreVideoToolsTests",
dependencies: ["CoreVideoTools"]
)
]
)
83 changes: 58 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,56 +1,89 @@
# core-video-tools
# CoreVideoTools

A set of extensions and utilities to work with [CoreVideo](https://developer.apple.com/documentation/corevideo?language=objc) types.
[![Platform Compatibility](https://img.shields.io/badge/Platforms-iOS%20|%20macOS-brightgreen)](https://swift.org/platforms/)
[![Swift Version](https://img.shields.io/badge/Swift-5.9-orange)](https://swift.org)

## CVPixelFormat
<p align="left">
<img src="Sources/CoreVideoTools/CoreVideoTools.docc/Resources/table-of-contents-art/[email protected]", width="120">
</p>

While debuging `Core Video` objects, you need to understand what pixel format is used in them.
To do this using vanilla API you are forced to find a mathing `OSType` value, because `OSType` if basically a number.
This project uses [`CVPixelFormat`](Sources/CoreVideoTools/CVPixelFormat.swift) enum istead of vanilla `OSType` public vars which is much more handy, and you can easyly get a `description` of a current pixel format.
## Overview

```swift
let cvPixelFormat: CVPixelFormat = cvPixelBuffer.cvPixelFormat
let description = cvPixelFormat.description
```
CoreVideoTools offers a more idiomatic Swift interface to `CoreVideo` functionality, making it easier and safer to work with `CVPixelBuffers`, `IOSurfaces`, and related `CoreVideo` concepts in Swift code.

Please see [the package's documentation](https://swiftpackageindex.com/computer-graphics-tools/core-video-tools/documentation/corevideotools)
for more detailed usage instructions.

## Swifty API
## CVPixelBuffer

There are a lot Swift wrappers over vanilla CVPixelBuffer C-style API:

**Vanilla API:**
**Swifty API:**

```swift
let width = CVPixelBufferGetWidth(cvPixelBuffer)
let height = CVPixelBufferGetHeight(cvPixelBuffer)
let width = pixelBuffer.width
let height = pixelBuffer.height
let format = pixelBuffer.cvPixelFormat
let bytesPerRow = pixelBuffer.bytesPerRow
```

// ...
**Convenience Init:**

let bytesPerElement = IOSurfaceGetBytesPerRow(ioSurface)
let bytesPerRow = IOSurfaceGetBytesPerRow(ioSurface)
```swift
let pixelBuffer = try CVPixelBuffer.create(
width: 1920,
height: 1080,
cvPixelFormat: .type_32BGRA
)
```

**Swifty API:**
Check out more examples in the [Working With CVPixelBuffer](Sources/CoreVideoTools/CoreVideoTools.docc/WorkingWithCVPixelBuffer.md).

## IOSurface

**Convenience Init:**

```swift
let width = cvPixelBuffer.width
let height = cvPixelBuffer.height
let surface = try IOSurface.create(
width: 1920,
height: 1080,
cvPixelFormat: .type_32BGRA,
bytesPerElement: 4,
bytesPerRow: 1920 * 4
)
```

For more detail, please checkout [Working With IOSurface](Sources/CoreVideoTools/CoreVideoTools.docc/WorkingWithIOSurface.md).

// ...
## CVPixelFormat

While debuging `Core Video` objects, you need to understand what pixel format is used in them.
To do this using vanilla API you are forced to find a matching `OSType` value, because `OSType` if basically a number.
This project uses [`CVPixelFormat`](Sources/CoreVideoTools/CVPixelFormat.swift) enum istead of vanilla `OSType` public vars which is much more handy, and you can easily get a `description` of a current pixel format.

let bytesPerElement = ioSurface.bytesPerElement
let bytesPerRow = ioSurface.bytesPerRow
```swift
let cvPixelFormat: CVPixelFormat = cvPixelBuffer.cvPixelFormat
let description = cvPixelFormat.description
```

## CVReturn Result & CVError

There are some functions in Core Video that return a code which helps if the operation succeeded.
There are some functions in Core Video that return a code which helps if the operation succeeded.
This project aims to simplify this error checking. `CVReturn` [`Result`](Sources/CoreVideoTools/Extensions/CoreVideo/CVReturn/CVReturn+Result.swift) and [`CVError`](Sources/CoreVideoTools/CVError.swift) types are used to wrap vanilla API with thowable functions.

**Vanilla API:**

```swift
let returnCode = CVPixelBufferLockBaseAddress(cvPixelBuffer, lockFlags)
guard returnCode == kCVReturnSuccess else { // handle the error ...
guard returnCode == kCVReturnSuccess else { /* handle the error ... */ }
```

**Swifty API:**

```swift
try cvPixelBuffer.lockBaseAddress(lockFlags: lockFlags)
```

## License

MetalTools is licensed under [MIT license](LICENSE).
18 changes: 9 additions & 9 deletions Sources/CoreVideoTools/CVError.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import CoreVideo

/// CoreVideo specific error codes
/// Represents CoreVideo specific error codes.
public enum CVError: Error, Equatable {
/// An otherwise undefined error occurred.
case error
/// At least one of the arguments passed in is not valid. Either out of range or the wrong type.
case invalidArgument
/// The allocation for a buffer or buffer pool failed. Most likely because of lack of resources.
case allocationFailed
/// The operation or feature is not supported.
case unsupported

// DisplayLink related errors
Expand All @@ -23,15 +22,15 @@ public enum CVError: Error, Equatable {

// Buffer related errors

/// The requested pixelformat is not supported for the CVBuffer type.
/// The requested pixel format is not supported for the CVBuffer type.
case invalidPixelFormat
/// The requested size (most likely too big) is not supported for the CVBuffer type.
case invalidSize
/// A CVBuffer cannot be created with the given attributes.
case invalidPixelBufferAttributes
/// The Buffer cannot be used with OpenGL as either its size, pixelformat or attributes are not supported by OpenGL.
/// The Buffer cannot be used with OpenGL as either its size, pixel format or attributes are not supported by OpenGL.
case pixelBufferNotOpenGLCompatible
/// The Buffer cannot be used with Metal as either its size, pixelformat or attributes are not supported by Metal.
/// The Buffer cannot be used with Metal as either its size, pixel format or attributes are not supported by Metal.
case pixelBufferNotMetalCompatible

// Buffer Pool related errors
Expand All @@ -45,8 +44,9 @@ public enum CVError: Error, Equatable {
/// A scan hasn't completely traversed the CVBufferPool due to a concurrent operation. The client can retry the scan.
case retry

/// Initialize `CVError` value.
/// - Parameter rawValue: vanilla `CVReturn` value.
/// Initializes a `CVError` value from a raw `CVReturn` value.
/// - Parameter rawValue: The vanilla `CVReturn` value.
/// - Returns: The corresponding `CVError` instance.
public init(rawValue: CVReturn) {
switch rawValue {
case kCVReturnInvalidArgument: self = .invalidArgument
Expand All @@ -69,7 +69,7 @@ public enum CVError: Error, Equatable {
}
}

/// Vanilla `CVReturn` value.
/// The raw `CVReturn` value corresponding to this `CVError`.
public var rawValue: CVReturn {
switch self {
case .error: return kCVReturnError
Expand Down
14 changes: 7 additions & 7 deletions Sources/CoreVideoTools/CVPixelFormat.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
@_exported import CoreVideo
@_exported import IOSurface
import Foundation

/// Represents various pixel format types used in Core Video.
public enum CVPixelFormat: CustomStringConvertible, CaseIterable, Codable {
/// 1 bit indexed
case type_1Monochrome
Expand Down Expand Up @@ -215,9 +214,10 @@ public enum CVPixelFormat: CustomStringConvertible, CaseIterable, Codable {
/// Format is compressed-packed with no padding bits between pixels.
case type_Lossy_422YpCbCr10PackedBiPlanarVideoRange
case unknown

/// Initialize `CVPixelFormat`.
/// - Parameter rawValue: vanilla `OSType` value.

/// Initializes a `CVPixelFormat` instance from a raw `OSType` value.
/// - Parameter rawValue: The raw `OSType` value representing a pixel format.
/// - Returns: The corresponding `CVPixelFormat` instance, or `.unknown` if the value is not recognized.
public init(rawValue: OSType) {
switch rawValue {
case kCVPixelFormatType_1Monochrome: self = .type_1Monochrome
Expand Down Expand Up @@ -315,7 +315,7 @@ public enum CVPixelFormat: CustomStringConvertible, CaseIterable, Codable {
}
}

/// Vanilla `OSType` value.
/// The raw `OSType` value corresponding to this pixel format.
public var rawValue: OSType {
switch self {
case .type_1Monochrome: return kCVPixelFormatType_1Monochrome
Expand Down Expand Up @@ -413,7 +413,7 @@ public enum CVPixelFormat: CustomStringConvertible, CaseIterable, Codable {
}
}

/// The description of the pixel format.
/// A human-readable description of the pixel format.
public var description: String {
switch self {
case .type_1Monochrome: return "1Monochrome"
Expand Down
39 changes: 39 additions & 0 deletions Sources/CoreVideoTools/CoreVideoTools.docc/CoreVideoTools.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# ``CoreVideoTools``

![CoreVideoTools](core-video-tools.png)

CoreVideo Tools offers a more idiomatic Swift interface to CoreVideo functionality, making it easier and safer to work with pixel buffers, IOSurfaces, and related CoreVideo concepts in Swift code.

## Topics

### Articles

- <doc:WorkingWithCVPixelBuffer>
- <doc:WorkingWithIOSurface>

### CVPixelBuffer Extensions

- ``CoreVideo/CVBuffer/width``
- ``CoreVideo/CVBuffer/height``
- ``CoreVideo/CVBuffer/cvPixelFormat``
- ``CoreVideo/CVBuffer/baseAddress``
- ``CoreVideo/CVBuffer/bytesPerRow``
- ``CoreVideo/CVBuffer/lockBaseAddress(lockFlags:)``
- ``CoreVideo/CVBuffer/unlockBaseAddress(unlockFlags:)``
- ``CoreVideo/CVBuffer/create(width:height:cvPixelFormat:attachments:allocator:)``
- ``CoreVideo/CVBuffer/blankCopy()``
- ``CoreVideo/CVBuffer/deepCopy()``

### IOSurface Extensions

- ``IOSurface/IOSurface/CacheMode``
- ``IOSurface/IOSurface/create(width:height:cvPixelFormat:bytesPerElement:bytesPerRow:cacheMode:additionalProperties:)``

### Error Handling

- ``CVError``
- ``Swift/Int32/Result``

### Pixel Formats

- ``CVPixelFormat``
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading