Compare commits

...

6 Commits

Author SHA1 Message Date
12fbb0ce77 Update .gitignore to exclude linter files 2024-09-22 23:14:40 +02:00
bd9b4f8288 Start custom ffmpeg implementation
For now, only device scanning is working
2024-09-22 23:13:32 +02:00
a938be7e5b Get ffmpeg example code to work 2024-09-22 17:58:26 +02:00
a2e78ad621 Simplify .gitignore
Build system puts everything in bin folder so we don't need individual rules and
can simply ignore the whole folder
2024-09-22 17:26:06 +02:00
5e748a96af Setup basic hello world
Adds minimal Makefile and main.c
2024-09-22 17:24:13 +02:00
ca539639a5 Add ctags files to gitignore 2024-09-22 17:04:57 +02:00
5 changed files with 301 additions and 49 deletions

56
.gitignore vendored
View File

@ -1,54 +1,12 @@
# ---> C
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Output folder
bin
# Linker output
*.ilk
*.map
*.exp
# Ctag files
tags
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
# Linter files
compile_commands.json
.cache

164
Makefile Normal file
View File

@ -0,0 +1,164 @@
# --- minimal linux makefile ------------------------------------------------- #
# This makefile works on linux with options to crosscompile by changing the #
# TARGET option. By default, compile the defined application for the native #
# platform. #
# #
# Before use, make sure to adapt the parameters in the following sections #
# - project architecture : general folder layout #
# - toolchain configuration : compiler to use and other little things #
# - defines settings : list of defines to pass to the compiler #
# - general settings : include control and release options #
# ---------------------------------------------------------------------------- #
# --- project architecture
# program name
EXE_PREFIX=main
# project folder architecture
SRC=src
BIN=bin
INC=
OBJ=$(BIN)/obj
# --- toolchain configuration
TARGET=
CC=$(TARGET)gcc
AS=$(TARGET)gcc -x assembler-with-cpp -c
# --- defines settings
#list all C defines here with -D before the name
C_DEFS=
#list all ASM defines here with -D before the name
A_DEFS=
#list all linker flags here with -l before the name
LDFLAGS=-lavcodec -lavformat -lavutil -lavdevice -lv4l2
# --- general settings
# RELEASE=0 -> disable optimisation, then enable debug
# RELEASE=1 -> enable optimisation, then disable debug
RELEASE=0
#-------------------------------------------------------------------------------
# files discovery and paths solving
# down here is black magic, you probably don't want to modify anything
#list all directories, sort them and remove duplicates
DIRS:=$(sort $(shell find . -type d))
#find paths to src files from directory list
SRC_PATHS=$(foreach DIR, $(SRC), $(filter ./$(DIR)%, $(DIRS)))
#list c files
C_FILES=$(foreach PATH, . $(SRC_PATHS), $(wildcard $(PATH)/*.c))
#filter useless STmcube files
ifeq ($(strip $(FILTER)), 1)
C_FILES:=$(filter-out %template.c, $(C_FILES))
endif
#list h files
#H_FILES=$(foreach PATH, $(INC_PATHS), $(wildcard $(PATH)/*.h))
#list asm files
ASM_FILES=$(foreach PATH, . $(SRC_PATHS), $(wildcard $(PATH)/*.s))
#separate main c file from other c files
MAIN_C_FILES:=$(filter %$(EXE_PREFIX).c, $(C_FILES))
C_FILES:=$(filter-out %$(EXE_PREFIX).c, $(C_FILES))
#create new paths to store o files
MAIN_OBJ_FILES=$(patsubst ./%.c, ./$(OBJ)/%.o, $(MAIN_C_FILES))
OBJ_FILES=$(patsubst ./%.c, ./$(OBJ)/%.o, $(C_FILES)) \
$(patsubst ./%.s, ./$(OBJ)/%.o, $(ASM_FILES))
DEPEND_FILES=$(MAIN_OBJ_FILES:%.o,%.d)$(OBJ_FILES:%.o,%.d)
#-------------------------------------------------------------------------------
# makefile incantation
# --- include path flag management
ifneq ($(strip $(INC)),)
INCLUDE=-I$(INC)
else
INCLUDE=
endif
# --- release flag management
ifeq ($(strip $(RELEASE)), 0)
CFLAGS=-g3 -Os
LDFLAGS+=-g3 -Os
else
CFLAGS=-O2
endif
# --- flags definition
#merge all c compiler options
CFLAGS+=$(CPUFLAGS) -std=c23 -Wall -Wextra -Warray-bounds \
-Wno-unused-parameter -fomit-frame-pointer $(C_DEFS)
#merge all asm compiler options
ASFLAG=-Wa,--gdwarf2 -D__ASSEMBLY__ $(C_DEFS) $(A_DEFS)
#merge all linker options
LDFLAGS+=-lc -lgcc -lgcov -lm -Wl,-Map=$@.map,--gc-sections
# --- folder creation
DIR_GUARD=@mkdir -p $(@D)
#-------------------------------------------------------------------------------
# makefile rules
# --- main rule
all: $(BIN)/$(EXE_PREFIX)
# --- rules configuration
rebuild : clean all
.SUFFIXES:
.SECONDARY:
#define rules name
.PHONY: all clean rebuild
# --- secondary rules
#exec file compilation
$(BIN)/$(EXE_PREFIX) : $(MAIN_OBJ_FILES) $(OBJ_FILES)
@echo
@printf '\e[1;32m==== linking $@ ====\e[0m'
@echo
$(DIR_GUARD)
$(CC) $(LIBRARIES) $(LDFLAGS) $(CFLAGS) -o $@ $^
@$(SKIP_LINE)
#c files compilation
$(OBJ)/%.o : %.c
@echo
@printf '\e[1;34m==== compiling [opt=$(opt)] $< ====\e[0m'
@echo
$(DIR_GUARD)
$(CC) $(INCLUDE) -c $(CFLAGS) $< -o $@ $(LIBRARIES)
@$(SKIP_LINE)
$(BIN)/%.o : %.c
@echo
@printf '\e[1;34m==== compiling [opt=$(opt)] $< ====\e[0m'
@echo
$(DIR_GUARD)
$(CC) $(INCLUDE) -c $(CFLAGS) $< -o $@ $(LIBRARIES)
@$(SKIP_LINE)
#asm files compilation
$(OBJ)/%.o : %.s
@echo
@printf '\e[1;35m==== compiling [opt=$(opt)] $^ $@ $(LIBRARIES)====\e[0m'
@echo
$(DIR_GUARD)
$(AS) $(ASFLAGS) $< -o $@ $(LIBRARIES)
@$(SKIP_LINE)
$(BIN)/%.o : %.s
@echo
@printf '\e[1;35m==== compiling [opt=$(opt)] $^ $@ $(LIBRARIES)====\e[0m'
@echo
$(DIR_GUARD)
$(AS) $(ASFLAGS) $< -o $@ $(LIBRARIES)
@$(SKIP_LINE)
# --- remove generated files
clean:
-rm -rf $(BIN)/*
-include $(DEPEND_FILES)

98
src/ffmpeg.c Normal file
View File

@ -0,0 +1,98 @@
/** @file ffmpeg.c
*
*/
//--includes--------------------------------------------------------------------
#include <libavdevice/avdevice.h>
#include <time.h> //required by videodev2.h
#include <linux/videodev2.h>
#include <libv4l2.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
//--local definitions-----------------------------------------------------------
const AVDeviceInfo* find_h264_device(const AVDeviceInfoList* device_list);
//--local variables-------------------------------------------------------------
//--public functions------------------------------------------------------------
int ffmpeg_init(void)
{
avdevice_register_all();
const AVInputFormat* v4l2_format = av_find_input_format("v4l2");
AVDeviceInfoList* device_info_list;
int device_nb = avdevice_list_input_sources(v4l2_format, nullptr, nullptr,
&device_info_list);
if (device_nb < 0) {
fprintf(stderr, "Failed to list available devices\n");
avdevice_free_list_devices(&device_info_list);
return -1;
} else if (device_nb == 0) {
fprintf(stderr, "No compatible input device found\n");
avdevice_free_list_devices(&device_info_list);
return -1;
}
const AVDeviceInfo* device = find_h264_device(device_info_list);
if (device == nullptr) {
fprintf(stderr, "No H264 device found\n");
avdevice_free_list_devices(&device_info_list);
return -1;
}
printf("Found compatible device: %s\n%s\n",
device->device_name,
device->device_description);
avdevice_free_list_devices(&device_info_list);
return 0;
}
void ffmpeg_deinit()
{
}
//--local functions-------------------------------------------------------------
const AVDeviceInfo* find_h264_device(const AVDeviceInfoList* device_list)
{
for (int i=0; i<device_list->nb_devices; ++i) {
const AVDeviceInfo* device = device_list->devices[i];
int fd;
if ((fd = v4l2_open(device->device_name, O_RDWR)) < 0) {
fprintf(stderr, "Failed to open: %s, ignoring...\n",
device->device_name);
continue;
}
bool found = false;
struct v4l2_fmtdesc fmt;
fmt.index = 0;
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
while (v4l2_ioctl(fd, VIDIOC_ENUM_FMT, &fmt) >= 0) {
if (fmt.pixelformat == V4L2_PIX_FMT_H264) {
found = true;
break;
}
++fmt.index;
}
v4l2_close(fd);
if (found == true) {
return device;
}
}
return nullptr;
}

22
src/ffmpeg.h Normal file
View File

@ -0,0 +1,22 @@
/** @file ffmpeg.h
*
*/
//--includes--------------------------------------------------------------------
#include <stdint.h>
//--local definitions-----------------------------------------------------------
//--local variables-------------------------------------------------------------
//--public functions------------------------------------------------------------
int ffmpeg_init();
int ffmpeg_deinit();
int ffmpeg_read_frame(uint8_t* some_data);
//--local functions-------------------------------------------------------------

10
src/main.c Normal file
View File

@ -0,0 +1,10 @@
#include "ffmpeg.h"
int main(void)
{
ffmpeg_init();
ffmpeg_deinit();
return 0;
}