Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
e6d9c86
Better code comments
wysaid Aug 7, 2025
9244005
Add pixel convert for c
wysaid Aug 7, 2025
6a72360
Better C interface export
wysaid Aug 7, 2025
1e51736
Add demo for C
wysaid Aug 7, 2025
e430ef8
Fix callback handlding err in C interface
wysaid Aug 7, 2025
319229c
Add accelerated implementation with NEON version
wysaid May 29, 2025
cb37a83
Fix NEON version compilation issues
wysaid May 29, 2025
7a4c17b
add build scripts
wysaid May 29, 2025
ee291d3
support windows arm64
wysaid May 29, 2025
7fd69ba
Add YUYV and UYVY format conversion to NEON backend
wysaid Aug 7, 2025
ca1bd70
Add corresponding enum types for NEON backend
wysaid Aug 7, 2025
02d418d
Optimize iOS Demo, support more options
wysaid Aug 7, 2025
fc86f36
Better support for high frame rate (60/120) mode on Apple devices
wysaid Aug 7, 2025
9269627
better comments
wysaid Aug 7, 2025
073af5d
Fix compile err
wysaid Aug 7, 2025
0dd27e4
Fix invalid backend checking
wysaid Aug 8, 2025
96cea16
Add missing tests
wysaid Aug 8, 2025
3bff10d
try fix neon acc
wysaid Aug 9, 2025
ee966cc
Bugfix: pass all tests of neon acc
wysaid Aug 11, 2025
f177f41
better comments
wysaid Aug 11, 2025
e908e86
Fix demo compile err
wysaid Aug 11, 2025
a01f0ed
Small fix
wysaid Aug 11, 2025
889b63f
better release tasks
wysaid Aug 11, 2025
1e252fc
Fix tests compile error when cross compiling
wysaid Aug 11, 2025
7a69741
Run arm64 linux unit tests in PRs
wysaid Aug 11, 2025
5c2a306
Fix critical issues from AI code review comments
Copilot Aug 12, 2025
8211772
Address cross-platform compatibility and exception handling issues
Copilot Aug 12, 2025
170a691
Fix duplicate headings in scripts README.md
Copilot Aug 12, 2025
31db9ea
Simplify the overall design of the example to make the structure clea…
wysaid Aug 13, 2025
6df9632
When compiling for arm64, fix the restriction on the latest system ve…
wysaid Aug 13, 2025
271f821
Small fix
wysaid Aug 13, 2025
a143475
Simplify the examples
wysaid Aug 13, 2025
8ca622d
Fix compile err
wysaid Aug 13, 2025
4a12d2a
Initial plan for optimizing CcapDeviceInfo structure
Copilot Aug 13, 2025
9d156bf
Optimize CcapDeviceInfo structure with fixed-size arrays
Copilot Aug 13, 2025
7c44b74
Add optimized device names API and update all examples
Copilot Aug 13, 2025
ad67e02
Complete API optimization - remove legacy functions completely
Copilot Aug 13, 2025
8ebac50
Add workflow
wysaid Aug 13, 2025
d7a46ad
better examples
wysaid Aug 13, 2025
6ee3042
Use user context instead of global vars
wysaid Aug 13, 2025
470bf4e
Add more tasks
wysaid Aug 13, 2025
7977aab
Fix some bad practices and compilation warnings
wysaid Aug 13, 2025
fcfb85b
Add interface description
wysaid Aug 13, 2025
000062a
Remove trailing commas in tasks.json
wysaid Aug 13, 2025
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ build/
.idea/
dev.cmake
/install
build-*
34 changes: 34 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,40 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13" CACHE STRING "Minimum OS X deployment version")

# Unified ARM64 force compilation option, supports both macOS and Windows
option(CCAP_FORCE_ARM64 "Force ARM64 architecture compilation" OFF)

if(CCAP_FORCE_ARM64)
if(APPLE)
set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE STRING "Build architectures for Mac OS X" FORCE)
message(STATUS "ccap: Forcing ARM64 architecture compilation for macOS")
elseif(WIN32)
Comment thread
wysaid marked this conversation as resolved.
set(CMAKE_GENERATOR_PLATFORM "ARM64" CACHE STRING "Generator platform for Windows" FORCE)
message(STATUS "ccap: Forcing ARM64 architecture compilation for Windows")
endif()
endif()

# 检测 ARM64 架构并设置相应的编译标志
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64" OR
CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64" OR
CMAKE_OSX_ARCHITECTURES MATCHES "arm64" OR
CCAP_FORCE_ARM64)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

message(STATUS "ccap: Building for ARM64 architecture")

# Windows ARM64 特定设置
if(WIN32 AND MSVC)
# MSVC 在 ARM64 上自动启用 NEON,添加预处理器定义
add_compile_definitions(_M_ARM64=1)
message(STATUS "ccap: NEON support enabled for Windows ARM64")
endif()

# macOS ARM64 特定设置
if(APPLE)
message(STATUS "ccap: NEON support enabled for macOS ARM64")
endif()
endif()

if(NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
endif()
Expand Down
104 changes: 104 additions & 0 deletions examples/desktop/1-minimal_example_c.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/**
* @file 1-minimal_example_c.c
* @brief Minimal example demonstrating the use of ccap C interface
* @author wysaid (this@wysaid.org)
* @date 2025-05
*/

#include "ccap_c.h"
#include "ccap_utils_c.h"

#include <stdio.h>
#include <stdlib.h>

Comment thread
wysaid marked this conversation as resolved.
int selectCamera(CcapProvider* provider) {
char** deviceNames;
size_t deviceCount;

if (ccap_provider_find_device_names(provider, &deviceNames, &deviceCount) && deviceCount > 1) {
printf("Multiple devices found, please select one:\n");
for (size_t i = 0; i < deviceCount; i++) {
printf(" %zu: %s\n", i, deviceNames[i]);
}

int selectedIndex;
printf("Enter the index of the device you want to use: ");
if (scanf("%d", &selectedIndex) != 1) {
selectedIndex = 0;
}

if (selectedIndex < 0 || selectedIndex >= (int)deviceCount) {
selectedIndex = 0;
fprintf(stderr, "Invalid index, using the first device: %s\n", deviceNames[0]);
} else {
printf("Using device: %s\n", deviceNames[selectedIndex]);
}

ccap_provider_free_device_names(deviceNames, deviceCount);
return selectedIndex;
}

if (deviceCount > 0) {
ccap_provider_free_device_names(deviceNames, deviceCount);
}

return -1; // One or no device, use default.
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

int main() {
printf("ccap C Interface Minimal Example\n");
printf("Version: %s\n\n", ccap_get_version());

// Create provider
CcapProvider* provider = ccap_provider_create();
if (!provider) {
printf("Failed to create provider\n");
return -1;
}

// Select and open camera
int deviceIndex = selectCamera(provider);
if (!ccap_provider_open_by_index(provider, deviceIndex, true)) {
printf("Failed to open camera\n");
ccap_provider_destroy(provider);
return -1;
}

Comment thread
wysaid marked this conversation as resolved.
if (!ccap_provider_is_started(provider)) {
fprintf(stderr, "Failed to start camera!\n");
ccap_provider_destroy(provider);
return -1;
}

printf("Camera started successfully\n");

// Capture 10 frames
for (int i = 0; i < 10; i++) {
CcapVideoFrame* frame = ccap_provider_grab(provider, 3000); // 3 second timeout
if (frame) {
CcapVideoFrameInfo frameInfo;
if (ccap_video_frame_get_info(frame, &frameInfo)) {
// Get pixel format string
char formatStr[64];
ccap_pixel_format_to_string(frameInfo.pixelFormat, formatStr, sizeof(formatStr));

printf("VideoFrame %llu grabbed: width = %d, height = %d, bytes: %d, format: %s\n",
frameInfo.frameIndex, frameInfo.width, frameInfo.height,
frameInfo.sizeInBytes, formatStr);
}

ccap_video_frame_release(frame);
} else {
fprintf(stderr, "Failed to grab frame!\n");
ccap_provider_destroy(provider);
return -1;
}
}

printf("Captured 10 frames, stopping...\n");

// Cleanup
ccap_provider_destroy(provider);

return 0;
}
172 changes: 172 additions & 0 deletions examples/desktop/2-capture_grab_c.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/**
* @file 2-capture_grab_c.c
* @brief Example demonstrating frame capture with grab method using ccap C interface
* @author wysaid (this@wysaid.org)
* @date 2025-05
*/

#include "ccap_c.h"
#include "ccap_utils_c.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>

int selectCamera(CcapProvider* provider) {
char** deviceNames;
size_t deviceCount;

if (ccap_provider_find_device_names(provider, &deviceNames, &deviceCount) && deviceCount > 1) {
printf("Multiple devices found, please select one:\n");
for (size_t i = 0; i < deviceCount; i++) {
printf(" %zu: %s\n", i, deviceNames[i]);
}

int selectedIndex;
printf("Enter the index of the device you want to use: ");
if (scanf("%d", &selectedIndex) != 1) {
selectedIndex = 0;
}

if (selectedIndex < 0 || selectedIndex >= (int)deviceCount) {
selectedIndex = 0;
fprintf(stderr, "Invalid index, using the first device: %s\n", deviceNames[0]);
} else {
printf("Using device: %s\n", deviceNames[selectedIndex]);
}

ccap_provider_free_device_names(deviceNames, deviceCount);
return selectedIndex;
}

if (deviceCount > 0) {
ccap_provider_free_device_names(deviceNames, deviceCount);
}

return -1; // One or no device, use default.
}

void createDirectory(const char* path) {
struct stat st = {0};
if (stat(path, &st) == -1) {
mkdir(path, 0700);
}
}
Comment thread
wysaid marked this conversation as resolved.
Outdated

int main(int argc, char** argv) {
printf("ccap C Interface Capture Grab Example\n");
printf("Version: %s\n\n", ccap_get_version());

// Enable verbose log to see debug information
ccap_set_log_level(CCAP_LOG_LEVEL_VERBOSE);

// Get current working directory and create capture directory
char cwd[1024];
if (argc > 0 && argv[0][0] != '.') {
strncpy(cwd, argv[0], sizeof(cwd) - 1);
cwd[sizeof(cwd) - 1] = '\0';

// Find last slash
char* lastSlash = strrchr(cwd, '/');
if (!lastSlash) {
lastSlash = strrchr(cwd, '\\');
}
if (lastSlash) {
*lastSlash = '\0';
}
} else {
if (!getcwd(cwd, sizeof(cwd))) {
strcpy(cwd, ".");
}
}

char captureDir[1024];
snprintf(captureDir, sizeof(captureDir), "%s/image_capture", cwd);
createDirectory(captureDir);

// Create provider
CcapProvider* provider = ccap_provider_create();
if (!provider) {
printf("Failed to create provider\n");
return -1;
}

// Set camera properties
int requestedWidth = 1920;
int requestedHeight = 1080;
double requestedFps = 60.0;

ccap_provider_set_property(provider, CCAP_PROPERTY_WIDTH, requestedWidth);
ccap_provider_set_property(provider, CCAP_PROPERTY_HEIGHT, requestedHeight);
ccap_provider_set_property(provider, CCAP_PROPERTY_PIXEL_FORMAT_OUTPUT, CCAP_PIXEL_FORMAT_RGB24);
ccap_provider_set_property(provider, CCAP_PROPERTY_FRAME_RATE, requestedFps);

// Select and open camera
int deviceIndex;
if (argc > 1 && isdigit(argv[1][0])) {
deviceIndex = atoi(argv[1]);
} else {
deviceIndex = selectCamera(provider);
}

if (!ccap_provider_open_by_index(provider, deviceIndex, true)) {
printf("Failed to open camera\n");
ccap_provider_destroy(provider);
return -1;
}

if (!ccap_provider_is_started(provider)) {
fprintf(stderr, "Failed to start camera!\n");
ccap_provider_destroy(provider);
return -1;
}

// Get actual camera properties
int realWidth = (int)ccap_provider_get_property(provider, CCAP_PROPERTY_WIDTH);
int realHeight = (int)ccap_provider_get_property(provider, CCAP_PROPERTY_HEIGHT);
double realFps = ccap_provider_get_property(provider, CCAP_PROPERTY_FRAME_RATE);

printf("Camera started successfully, requested resolution: %dx%d, real resolution: %dx%d, requested fps %.1f, real fps: %.1f\n",
requestedWidth, requestedHeight, realWidth, realHeight, requestedFps, realFps);

// Capture frames with 3000ms timeout
int frameCount = 0;
while (frameCount < 10) {
CcapVideoFrame* frame = ccap_provider_grab(provider, 3000);
if (frame) {
CcapVideoFrameInfo frameInfo;
if (ccap_video_frame_get_info(frame, &frameInfo)) {
printf("VideoFrame %llu grabbed: width = %d, height = %d, bytes: %d\n",
frameInfo.frameIndex, frameInfo.width, frameInfo.height, frameInfo.sizeInBytes);

// Save frame to directory
char outputPath[2048];
int result = ccap_dump_frame_to_directory(frame, captureDir, outputPath, sizeof(outputPath));
if (result > 0) {
printf("VideoFrame saved to: %s\n", outputPath);
} else {
fprintf(stderr, "Failed to save frame!\n");
}
}

ccap_video_frame_release(frame);
frameCount++;

if (frameCount >= 10) {
printf("Captured 10 frames, stopping...\n");
break;
}
} else {
fprintf(stderr, "Failed to grab frame or timeout!\n");
break;
}
}

// Cleanup
ccap_provider_destroy(provider);

return 0;
}
Loading
Loading