Skip to content

Commit

Permalink
API and documentation update
Browse files Browse the repository at this point in the history
  • Loading branch information
eugenebokhan committed Jun 28, 2024
1 parent b0a6d07 commit b6b7679
Show file tree
Hide file tree
Showing 20 changed files with 786 additions and 530 deletions.
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

0 comments on commit b6b7679

Please sign in to comment.