-
Notifications
You must be signed in to change notification settings - Fork 1
Add example CLI project #25
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
1.0.0 | ||
1.0.2 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
cmake_minimum_required (VERSION 3.9) | ||
|
||
set(TARGET libvxcli) | ||
|
||
include_directories("${CMAKE_SOURCE_DIR}/src") | ||
|
||
add_executable(${TARGET} cli.c) | ||
|
||
target_link_libraries(${TARGET} PRIVATE ${FFMPEG_LIBS}) | ||
target_link_libraries(${TARGET} PRIVATE Griffeye.VideoProcessor.Native) | ||
target_link_libraries(${TARGET} PRIVATE m) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
#include <stdlib.h> | ||
#include <stdio.h> | ||
#include <stdbool.h> | ||
#include <string.h> | ||
#include <libavcodec/avcodec.h> | ||
#include <libavfilter/avfilter.h> | ||
#include <libavformat/avformat.h> | ||
|
||
#include "libvx.h" | ||
|
||
int main(int argc, char* argv[]) { | ||
int result = 1; | ||
char* video_path = argc > 1 ? argv[1] : ""; | ||
vx_video* video = NULL; | ||
vx_video_info* video_info = calloc(1, sizeof(vx_video_info)); | ||
vx_frame_info* frame_info = calloc(1, sizeof(vx_frame_info)); | ||
vx_frame* frame = NULL; | ||
|
||
vx_audio_params audio_params = { | ||
.channels = 2, | ||
.sample_format = VX_SAMPLE_FMT_FLT, | ||
.sample_rate = 44100 | ||
}; | ||
const vx_video_options options = { | ||
.audio_params = audio_params, | ||
.autorotate = true, | ||
.crop_area = {0}, | ||
.hw_criteria = VX_HW_ACCEL_ALL, | ||
.scene_threshold = 0.5 | ||
}; | ||
|
||
if (vx_open(video_path, options, &video, video_info) != VX_ERR_SUCCESS) { | ||
printf("Failed to open video: %s\n", video_path); | ||
goto cleanup; | ||
} | ||
|
||
// Initialize an empty frame that will be reused throughout the video | ||
frame = vx_frame_create(video, video_info->width, video_info->height, VX_PIX_FMT_RGB32); | ||
if (!frame) { | ||
printf("Failed to create frame\n"); | ||
goto cleanup; | ||
} | ||
|
||
// Iterate over all frames in the video. The frame is decoded when stepping | ||
while (vx_frame_step(video, frame_info) == VX_ERR_SUCCESS) { | ||
bool is_video_frame = frame_info->flags & VX_FF_HAS_IMAGE; | ||
|
||
printf("Frame: %ld, %dx%d\n", video->frame_count, frame_info->width, frame_info->height); | ||
|
||
// Perform processing and tranfer from GPU to CPU if necessary | ||
if (vx_frame_transfer_data(video, frame) != VX_ERR_SUCCESS) { | ||
printf("Failed to transfer frame data\n"); | ||
goto cleanup; | ||
} | ||
else { | ||
printf("Frame type: %s\n", is_video_frame ? "video" : "audio"); | ||
// The frame image could be accessed via frame->buffer | ||
// Alternatively for audio frames, the audio samples could be accessed via frame->audio_data | ||
} | ||
} | ||
|
||
result = 0; | ||
|
||
cleanup: | ||
vx_close(video); | ||
if (video_info) { | ||
free(video_info); | ||
} | ||
if (frame) { | ||
vx_frame_destroy(frame); | ||
} | ||
if (frame_info) { | ||
free(frame_info); | ||
} | ||
|
||
return result; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,69 +31,32 @@ | |
static bool initialized = false; | ||
static vx_log_callback log_cb = NULL; | ||
|
||
struct vx_audio_info | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had to move these to the header file so they could be used in the new CLI |
||
{ | ||
double peak_level; | ||
double rms_level; | ||
double rms_peak; | ||
}; | ||
|
||
struct vx_scene_info | ||
{ | ||
double difference; | ||
double scene_score; | ||
bool new_scene; | ||
}; | ||
|
||
struct vx_frame | ||
{ | ||
int width; | ||
int height; | ||
vx_pix_fmt pix_fmt; | ||
int sample_count; | ||
int max_samples; | ||
|
||
vx_audio_info audio_info; | ||
vx_scene_info scene_info; | ||
|
||
uint8_t** audio_buffer; | ||
void* buffer; | ||
}; | ||
|
||
struct vx_frame_info | ||
{ | ||
int width; | ||
int height; | ||
double timestamp; | ||
vx_frame_flag flags; | ||
}; | ||
|
||
static vx_log_level av_to_vx_log_level(const int level) | ||
{ | ||
// See: lavu_log_constants | ||
switch (level) { | ||
case AV_LOG_QUIET: | ||
return VX_LOG_NONE; | ||
case AV_LOG_QUIET: | ||
return VX_LOG_NONE; | ||
|
||
case AV_LOG_PANIC: | ||
case AV_LOG_FATAL: | ||
return VX_LOG_FATAL; | ||
case AV_LOG_PANIC: | ||
case AV_LOG_FATAL: | ||
return VX_LOG_FATAL; | ||
|
||
case AV_LOG_ERROR: | ||
return VX_LOG_ERROR; | ||
case AV_LOG_ERROR: | ||
return VX_LOG_ERROR; | ||
|
||
case AV_LOG_WARNING: | ||
return VX_LOG_WARNING; | ||
case AV_LOG_WARNING: | ||
return VX_LOG_WARNING; | ||
|
||
case AV_LOG_INFO: | ||
case AV_LOG_VERBOSE: | ||
return VX_LOG_INFO; | ||
case AV_LOG_INFO: | ||
case AV_LOG_VERBOSE: | ||
return VX_LOG_INFO; | ||
|
||
case AV_LOG_DEBUG: | ||
return VX_LOG_DEBUG; | ||
case AV_LOG_DEBUG: | ||
return VX_LOG_DEBUG; | ||
|
||
default: | ||
return VX_LOG_NONE; | ||
default: | ||
return VX_LOG_NONE; | ||
} | ||
} | ||
|
||
|
@@ -558,13 +521,22 @@ void vx_close(vx_video* video) | |
swr_free(&video->swr_ctx); | ||
|
||
if (video->fmt_ctx) | ||
avformat_free_context(video->fmt_ctx); | ||
avformat_close_input(&video->fmt_ctx); | ||
|
||
for (int i = 0; i < video->frame_queue_count; i++) { | ||
av_frame_unref(video->frame_queue[i]); | ||
av_frame_free(&video->frame_queue[i]); | ||
} | ||
|
||
if (video->hw_device_ctx) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use the "måsvinge"? |
||
av_buffer_unref(&video->hw_device_ctx); | ||
|
||
if (video->audio_codec_ctx) | ||
avcodec_free_context(&video->audio_codec_ctx); | ||
|
||
if (video->video_codec_ctx) | ||
avcodec_free_context(&video->video_codec_ctx); | ||
|
||
free(video); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,13 +6,13 @@ extern "C" { | |
#endif | ||
|
||
#ifdef _MSC_VER | ||
// Microsoft | ||
// Microsoft | ||
#define VX_DECLSPEC __declspec(dllexport) | ||
#define VX_CDECL __cdecl | ||
#else | ||
// GCC | ||
// GCC | ||
#define VX_DECLSPEC __attribute__((visibility("default"))) | ||
#define VX_CDECL __attribute__((__cdecl__)) | ||
#define VX_CDECL | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make sure this change doesn't cause any issues on Linux |
||
#endif | ||
|
||
#define FRAME_QUEUE_SIZE 32 | ||
|
@@ -120,6 +120,43 @@ struct av_audio_params | |
AVRational time_base; | ||
}; | ||
|
||
struct vx_audio_info | ||
{ | ||
double peak_level; | ||
double rms_level; | ||
double rms_peak; | ||
}; | ||
|
||
struct vx_scene_info | ||
{ | ||
double difference; | ||
double scene_score; | ||
bool new_scene; | ||
}; | ||
|
||
struct vx_frame_info | ||
{ | ||
int width; | ||
int height; | ||
double timestamp; | ||
vx_frame_flag flags; | ||
}; | ||
|
||
struct vx_frame | ||
{ | ||
int width; | ||
int height; | ||
vx_pix_fmt pix_fmt; | ||
int sample_count; | ||
int max_samples; | ||
|
||
vx_audio_info audio_info; | ||
vx_scene_info scene_info; | ||
|
||
uint8_t** audio_buffer; | ||
void* buffer; | ||
}; | ||
|
||
struct vx_video_options | ||
{ | ||
vx_audio_params audio_params; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Building from the command line was not working (
cmake -S . -B build_linux/
) since CMAKE_BUILD_TYPE was not set at that stage. That mean that the ffmpeg packages couldn't be found because the path was incomplete.