Skip to content

Commit

Permalink
feat: Linux support
Browse files Browse the repository at this point in the history
  • Loading branch information
protyposis committed Nov 18, 2023
1 parent 03f0e29 commit 0ddfb0c
Show file tree
Hide file tree
Showing 23 changed files with 603 additions and 83 deletions.
15 changes: 15 additions & 0 deletions Dockerfile.libaurioffmpegproxytest
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# A simple image to test the Linux build of the aurioffmpegproxy library.
#
# Usage:
# 1. build native library (with cmake)
# 2. build image: docker build -f Dockerfile.libaurioffmpegproxytest --tag aurioffmpegproxy nativesrc/out/build/linux-debug/aurioffmpegproxy
# 3. run container: docker run -it --rm aurioffmpegproxy [mediafile]
#
# Expected output is "No source file specified" when no mediafile is specified.

FROM ubuntu:22.04

WORKDIR /aurioffmpegproxy
COPY . .

ENTRYPOINT [ "/aurioffmpegproxy/aurioffmpegproxy" ]
31 changes: 24 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,21 +122,38 @@ Requirements
------------

* Windows
* Visual Studio 2022
- Visual Studio 2022 (with CMake tools)
* Linux
- Ubuntu 22.04
- CMake
- Ninja
* .NET SDK 6.0


Build Instructions
------------------

1. Install dependencies
### Windows
1. Install build environment (see requirements above)
2. Install dependencies
- Run `install-deps.ps1` in PowerShell
2. Build native code in `cmd` (or open `.\nativesrc` project in VS 2022)
3. Build native code in `cmd` (or open `.\nativesrc` project in VS 2022)
- `"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" x64`
- `cmake .\nativesrc --preset x64-debug`
- `cmake --build .\nativesrc\out\build\x64-debug`
3. Build managed code (or open `.\src` in VS 2022)
- `dotnet build .\src -c Debug`
- `cmake nativesrc --preset x64-debug`
- `cmake --build nativesrc\out\build\x64-debug`
4. Build managed code (or open `.\src` in VS 2022)
- `dotnet build src -c Debug`

### Linux
1. Install build environment
- `apt install cmake ninja-build dotnet-sdk-6.0`
2. Install dependencies
- Run `install-deps.sh`
3. Build native code
- `cmake nativesrc --preset linux-debug`
- `cmake --build nativesrc/out/build/linux-debug`
4. Build managed code
- `dotnet build src -c LinuxDebug`


Documentation
Expand Down
10 changes: 10 additions & 0 deletions install-deps.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash
VERSION=ffmpeg-n6.0-latest-linux64-lgpl-shared-6.0
LOCALNAME=linux64
ARCHIVE=$VERSION.tar.xz
DEST=./libs/ffmpeg

wget -O $ARCHIVE https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/$ARCHIVE && \
tar xf $ARCHIVE -C $DEST && \
rm $ARCHIVE && \
mv $DEST/$VERSION $DEST/$LOCALNAME
1 change: 1 addition & 0 deletions libs/ffmpeg/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/win64
/linux64
2 changes: 1 addition & 1 deletion nativesrc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ if (POLICY CMP0141)
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
endif()

project ("aurio")
project ("aurio" C)

# Include sub-projects.
add_subdirectory ("aurioffmpegproxy")
17 changes: 11 additions & 6 deletions nativesrc/CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,11 @@
}
},
{
"name": "linux-debug",
"displayName": "Linux Debug",
"name": "linux-base",
"hidden": true,
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
Expand All @@ -77,10 +74,18 @@
}
}
},
{
"name": "linux-debug",
"displayName": "Linux Debug",
"inherits": "linux-base",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "linux-release",
"displayName": "Linux Release",
"inherits": "linux-debug",
"inherits": "linux-base",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
Expand Down
72 changes: 55 additions & 17 deletions nativesrc/aurioffmpegproxy/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
add_library (aurioffmpegproxy SHARED "proxy.c" "proxy.h" "seekindex.c" "seekindex.h")
# Force library to scan local directory for FFmpeg libs. Without it, `LD_LIBRARY_PATH=.` is needed.
# This must come before add_library/add_executable
set(CMAKE_BUILD_RPATH "$ORIGIN")

add_library (aurioffmpegproxy SHARED "proxy.c" "proxy.h" "seekindex.c" "seekindex.h")
add_executable (aurioffmpegproxy_exe "main.c")
set_property(TARGET aurioffmpegproxy_exe PROPERTY OUTPUT_NAME aurioffmpegproxy)
target_link_libraries(aurioffmpegproxy_exe aurioffmpegproxy)
Expand All @@ -7,23 +11,57 @@ if (CMAKE_VERSION VERSION_GREATER 3.12)
set_property(TARGET ${TARGET_NAME} PROPERTY CXX_STANDARD 20)
endif()

# FFmpeg
set(FFMPEG_PLATFORM win64)
if (WIN32)
set(FFMPEG_PLATFORM win64)
set(LIB_PREFIX "")
set(LIB_EXT .lib)
else()
set(FFMPEG_PLATFORM linux64)
set(LIB_PREFIX "lib")
set(LIB_EXT .so)
endif()

# No PkgConfig on Windows, and the hacky workaround works on Windows and Linux.
#find_package(PkgConfig REQUIRED)
#set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../libs/ffmpeg/${FFMPEG_PLATFORM}/")
#pkg_check_modules(LIBAV REQUIRED IMPORTED_TARGET
# libavcodec
# libavformat
# libavutil
# libswresample
# libswscale
#)
#target_link_libraries(aurioffmpegproxy PkgConfig::LIBAV)

set(FFMPEG_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../libs/ffmpeg/${FFMPEG_PLATFORM}/)
target_include_directories(aurioffmpegproxy PUBLIC ${FFMPEG_DIR}/include/)
target_link_libraries(aurioffmpegproxy PRIVATE
${FFMPEG_DIR}/lib/avcodec.lib
${FFMPEG_DIR}/lib/avformat.lib
${FFMPEG_DIR}/lib/avutil.lib
${FFMPEG_DIR}/lib/swresample.lib
${FFMPEG_DIR}/lib/swscale.lib
)
add_custom_command(TARGET aurioffmpegproxy POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${FFMPEG_DIR}/bin/avcodec-60.dll
${FFMPEG_DIR}/bin/avformat-60.dll
${FFMPEG_DIR}/bin/avutil-58.dll
${FFMPEG_DIR}/bin/swresample-4.dll
${FFMPEG_DIR}/bin/swscale-7.dll
$<TARGET_FILE_DIR:aurioffmpegproxy>
${FFMPEG_DIR}/lib/${LIB_PREFIX}avcodec${LIB_EXT}
${FFMPEG_DIR}/lib/${LIB_PREFIX}avformat${LIB_EXT}
${FFMPEG_DIR}/lib/${LIB_PREFIX}avutil${LIB_EXT}
${FFMPEG_DIR}/lib/${LIB_PREFIX}swresample${LIB_EXT}
${FFMPEG_DIR}/lib/${LIB_PREFIX}swscale${LIB_EXT}
)

# Copy libraries to build output directory
if (WIN32)
add_custom_command(TARGET aurioffmpegproxy POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${FFMPEG_DIR}/bin/avcodec-60.dll
${FFMPEG_DIR}/bin/avformat-60.dll
${FFMPEG_DIR}/bin/avutil-58.dll
${FFMPEG_DIR}/bin/swresample-4.dll
${FFMPEG_DIR}/bin/swscale-7.dll
$<TARGET_FILE_DIR:aurioffmpegproxy>
)
else()
add_custom_command(TARGET aurioffmpegproxy POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${FFMPEG_DIR}/lib/${LIB_PREFIX}avcodec${LIB_EXT}.60
${FFMPEG_DIR}/lib/${LIB_PREFIX}avformat${LIB_EXT}.60
${FFMPEG_DIR}/lib/${LIB_PREFIX}avutil${LIB_EXT}.58
${FFMPEG_DIR}/lib/${LIB_PREFIX}swresample${LIB_EXT}.4
${FFMPEG_DIR}/lib/${LIB_PREFIX}swscale${LIB_EXT}.7
$<TARGET_FILE_DIR:aurioffmpegproxy>
)
endif()
22 changes: 13 additions & 9 deletions nativesrc/aurioffmpegproxy/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
//
#include "proxy.h"

#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif

FILE* file_open(const char* filename) {
return fopen(filename, "rb");
}
Expand All @@ -29,11 +33,11 @@ int file_close(FILE* f) {
return fclose(f);
}

int file_read_packet(FILE* f, uint8_t* buf, int buf_size) {
int file_read_packet(void* f, uint8_t* buf, int buf_size) {
return (int)fread(buf, 1, buf_size, f);
}

int64_t file_seek(FILE* f, int64_t offset, int whence) {
int64_t file_seek(void* f, int64_t offset, int whence) {
if (whence == AVSEEK_SIZE) {
long current_pos = ftell(f); // temporarily save current position
fseek(f, 0, SEEK_END); // seek to end
Expand Down Expand Up @@ -84,14 +88,14 @@ int main(int argc, char* argv[])
//info(pi->fmt_ctx);

if (mode & TYPE_AUDIO) {
printf("audio length: %lld, frame size: %d\n", pi->audio_output.length, pi->audio_output.frame_size);
printf("audio length: %"PRId64", frame size: %d\n", pi->audio_output.length, pi->audio_output.frame_size);
printf("audio format (samplerate/samplesize/channels): %d/%d/%d\n",
pi->audio_output.format.sample_rate, pi->audio_output.format.sample_size, pi->audio_output.format.channels);

audio_output_buffer_size = pi->audio_output.frame_size * pi->audio_output.format.channels * pi->audio_output.format.sample_size;
}
if (mode & TYPE_VIDEO) {
printf("video length: %lld, frame size: %d\n", pi->video_output.length, pi->video_output.frame_size);
printf("video length: %"PRId64", frame size: %d\n", pi->video_output.length, pi->video_output.frame_size);
printf("video format (width/height/fps/aspect): %d/%d/%f/%f\n",
pi->video_output.format.width, pi->video_output.format.height, pi->video_output.format.frame_rate, pi->video_output.format.aspect_ratio);

Expand All @@ -103,7 +107,7 @@ int main(int argc, char* argv[])
// read full stream
int64_t count1 = 0, last_ts1 = -1;
while ((ret = stream_read_frame(pi, &timestamp, output_buffer, output_buffer_size, &frame_type)) >= 0) {
printf("read %d @ %lld type %d\n", ret, timestamp, frame_type);
printf("read %d @ %"PRId64" type %d\n", ret, timestamp, frame_type);
if (frame_type == TYPE_VIDEO) {
printf("keyframe %d, pict_type %d, interlaced %d, top_field_first %d\n",
pi->video_output.current_frame.keyframe, pi->video_output.current_frame.pict_type,
Expand All @@ -125,7 +129,7 @@ int main(int argc, char* argv[])
int64_t accumulated_frame_length = 0;
int last_ret = 0;
while ((ret = stream_read_frame(pi, &timestamp, output_buffer, output_buffer_size, &frame_type)) >= 0) {
printf("read %d @ %lld type %d\n", ret, timestamp, frame_type);
printf("read %d @ %"PRId64" type %d\n", ret, timestamp, frame_type);
count2++;
last_ts2 = timestamp;
if (frame_type == TYPE_AUDIO) {
Expand All @@ -135,16 +139,16 @@ int main(int argc, char* argv[])
}
int64_t length_from_last_ts = last_ts2 + last_ret; // last timestamp + frame length

printf("read1 count: %lld, timestamp: %lld\n", count1, last_ts1);
printf("read2 count: %lld, timestamp: %lld\n", count2, last_ts2);
printf("read1 count: %"PRId64", timestamp: %"PRId64"\n", count1, last_ts1);
printf("read2 count: %"PRId64", timestamp: %"PRId64"\n", count2, last_ts2);

if (mode & TYPE_AUDIO) {
// Print lengths from
// - the header,
// - summed over all frames,
// - and from the last timestamp + frame length
// to compare for inconsistencies.
printf("audio length header/accumulated/last_ts: %lld/%lld/%lld\n",
printf("audio length header/accumulated/last_ts: %"PRId64"/%"PRId64"/%"PRId64"\n",
pi->audio_output.length, accumulated_frame_length, length_from_last_ts);
}

Expand Down
Loading

0 comments on commit 0ddfb0c

Please sign in to comment.