-
Notifications
You must be signed in to change notification settings - Fork 29
Add support for NEON instruction acceleration, optimize the iOS demo, and enable frame rate and resolution switching settings. #4
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
Merged
Merged
Changes from 15 commits
Commits
Show all changes
44 commits
Select commit
Hold shift + click to select a range
e6d9c86
Better code comments
wysaid 9244005
Add pixel convert for c
wysaid 6a72360
Better C interface export
wysaid 1e51736
Add demo for C
wysaid e430ef8
Fix callback handlding err in C interface
wysaid 319229c
Add accelerated implementation with NEON version
wysaid cb37a83
Fix NEON version compilation issues
wysaid 7a4c17b
add build scripts
wysaid ee291d3
support windows arm64
wysaid 7fd69ba
Add YUYV and UYVY format conversion to NEON backend
wysaid ca1bd70
Add corresponding enum types for NEON backend
wysaid 02d418d
Optimize iOS Demo, support more options
wysaid fc86f36
Better support for high frame rate (60/120) mode on Apple devices
wysaid 9269627
better comments
wysaid 073af5d
Fix compile err
wysaid 0dd27e4
Fix invalid backend checking
wysaid 96cea16
Add missing tests
wysaid 3bff10d
try fix neon acc
wysaid ee966cc
Bugfix: pass all tests of neon acc
wysaid f177f41
better comments
wysaid e908e86
Fix demo compile err
wysaid a01f0ed
Small fix
wysaid 889b63f
better release tasks
wysaid 1e252fc
Fix tests compile error when cross compiling
wysaid 7a69741
Run arm64 linux unit tests in PRs
wysaid 5c2a306
Fix critical issues from AI code review comments
Copilot 8211772
Address cross-platform compatibility and exception handling issues
Copilot 170a691
Fix duplicate headings in scripts README.md
Copilot 31db9ea
Simplify the overall design of the example to make the structure clea…
wysaid 6df9632
When compiling for arm64, fix the restriction on the latest system ve…
wysaid 271f821
Small fix
wysaid a143475
Simplify the examples
wysaid 8ca622d
Fix compile err
wysaid 4a12d2a
Initial plan for optimizing CcapDeviceInfo structure
Copilot 9d156bf
Optimize CcapDeviceInfo structure with fixed-size arrays
Copilot 7c44b74
Add optimized device names API and update all examples
Copilot ad67e02
Complete API optimization - remove legacy functions completely
Copilot 8ebac50
Add workflow
wysaid d7a46ad
better examples
wysaid 6ee3042
Use user context instead of global vars
wysaid 470bf4e
Add more tasks
wysaid 7977aab
Fix some bad practices and compilation warnings
wysaid fcfb85b
Add interface description
wysaid 000062a
Remove trailing commas in tasks.json
wysaid File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,3 +3,4 @@ build/ | |
| .idea/ | ||
| dev.cmake | ||
| /install | ||
| build-* | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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> | ||
|
|
||
|
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. | ||
| } | ||
|
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; | ||
| } | ||
|
|
||
|
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; | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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); | ||
| } | ||
| } | ||
|
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; | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.