Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ jobs:
with:
submodules: 'recursive'

- name: Setup cmake
uses: jwlawson/actions-setup-cmake@v2
with:
cmake-version: '3.x'

- name: Configure CMake
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
Expand Down
75 changes: 75 additions & 0 deletions .github/workflows/kvsappcli.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
name: kvsappcli test

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
kvsappcli-on-mac:
runs-on: macos-15

permissions:
id-token: write
contents: read

env:
STREAM_NAME: kvs-producer-embedded-c-kvsappcli-macos
AWS_KVS_HOST: "kinesisvideo.us-west-2.amazonaws.com"

steps:
- uses: actions/checkout@v4
with:
submodules: 'recursive'

- name: Install dependencies
run: |
brew update
brew install coreutils # for gtimeout
brew install --cask mkvtoolnix

- name: Setup cmake
uses: jwlawson/actions-setup-cmake@v2
with:
cmake-version: '3.x'

- name: Fix the const issue
working-directory: ./libraries/amazon/amazon-kinesis-video-streams-media-interface
run: |
git apply ../../../patches/amazon-kinesis-video-streams-media-interface/const-fix.patch

- name: Build project
run: |
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE="Debug" -DENABLE_MKV_DUMP=ON
make -j

- name: Setup AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: us-west-2
role-to-assume: ${{ secrets.KVS_GITHUB_ACTIONS_ROLE_ARN }}

- name: Run the sample
working-directory: ./build
run: |
gtimeout --signal=SIGINT --kill-after=15s --preserve-status 30s ./bin/kvsappcli "$STREAM_NAME"

- name: Check MKV file
working-directory: ./build
run: |
if [ ! -f ./dumped_output.mkv ]; then
echo "❌ MKV file was not created!"
exit 1
fi

output="$(mkvinfo -v ./dumped_output.mkv)"
echo "$output"

if ! echo "$output" | grep "String: test_value_9"; then
echo "❌ No metadata found!"
exit 1
fi
shell: bash
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
build
cmake-build-debug

samples/kvs-esp32/sdkconfig.old
samples/kvs-esp32/components/llhttp/*
Expand Down
183 changes: 183 additions & 0 deletions patches/amazon-kinesis-video-streams-media-interface/const-fix.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
diff --git a/include/com/amazonaws/kinesis/video/capturer/AudioCapturer.h b/include/com/amazonaws/kinesis/video/capturer/AudioCapturer.h
index e0747f4..63d0c79 100644
--- a/include/com/amazonaws/kinesis/video/capturer/AudioCapturer.h
+++ b/include/com/amazonaws/kinesis/video/capturer/AudioCapturer.h
@@ -46,7 +46,7 @@ AudioCapturerHandle audioCapturerCreate(void);
* @param[in] handle Handle of AudioCapturer.
* @return AudioCapturerStatus
*/
-AudioCapturerStatus audioCapturerGetStatus(const AudioCapturerHandle const handle);
+AudioCapturerStatus audioCapturerGetStatus(const AudioCapturerHandle handle);

/**
* @brief Get capturer capability.
@@ -55,7 +55,7 @@ AudioCapturerStatus audioCapturerGetStatus(const AudioCapturerHandle const handl
* @param[out] pCapability Capturer capability.
* @return int 0 or error code.
*/
-int audioCapturerGetCapability(const AudioCapturerHandle const handle, AudioCapability* pCapability);
+int audioCapturerGetCapability(const AudioCapturerHandle handle, AudioCapability* pCapability);

/**
* @brief Set capturer format, channel number, bit depth and sample rate.
@@ -80,7 +80,7 @@ int audioCapturerSetFormat(AudioCapturerHandle handle, const AudioFormat format,
* @param[in] pBitDepth Frame bit depth.
* @return int 0 or error code.
*/
-int audioCapturerGetFormat(const AudioCapturerHandle const handle, AudioFormat* pFormat, AudioChannel* pChannel, AudioSampleRate* pSampleRate,
+int audioCapturerGetFormat(const AudioCapturerHandle handle, AudioFormat* pFormat, AudioChannel* pChannel, AudioSampleRate* pSampleRate,
AudioBitDepth* pBitDepth);

/**
diff --git a/include/com/amazonaws/kinesis/video/capturer/VideoCapturer.h b/include/com/amazonaws/kinesis/video/capturer/VideoCapturer.h
index 0b3671f..412625a 100644
--- a/include/com/amazonaws/kinesis/video/capturer/VideoCapturer.h
+++ b/include/com/amazonaws/kinesis/video/capturer/VideoCapturer.h
@@ -46,7 +46,7 @@ VideoCapturerHandle videoCapturerCreate(void);
* @param[in] handle Handle of VideoCapturer.
* @return VideoCapturerStatus Status of VideoCapturer.
*/
-VideoCapturerStatus videoCapturerGetStatus(const VideoCapturerHandle const handle);
+VideoCapturerStatus videoCapturerGetStatus(const VideoCapturerHandle handle);

/**
* @brief Get capturer capability.
@@ -55,7 +55,7 @@ VideoCapturerStatus videoCapturerGetStatus(const VideoCapturerHandle const handl
* @param[out] pCapability Capturer capability.
* @return int 0 or error code.
*/
-int videoCapturerGetCapability(const VideoCapturerHandle const handle, VideoCapability* pCapability);
+int videoCapturerGetCapability(const VideoCapturerHandle handle, VideoCapability* pCapability);

/**
* @brief Set capturer format and resolution.
@@ -75,7 +75,7 @@ int videoCapturerSetFormat(VideoCapturerHandle handle, const VideoFormat format,
* @param[out] pResolution Frame resolution.
* @return int 0 or error code.
*/
-int videoCapturerGetFormat(const VideoCapturerHandle const handle, VideoFormat* pFormat, VideoResolution* pResolution);
+int videoCapturerGetFormat(const VideoCapturerHandle handle, VideoFormat* pFormat, VideoResolution* pResolution);

/**
* @brief Acquire and turn on video stream.
diff --git a/include/com/amazonaws/kinesis/video/player/AudioPlayer.h b/include/com/amazonaws/kinesis/video/player/AudioPlayer.h
index db15477..2bf1c51 100644
--- a/include/com/amazonaws/kinesis/video/player/AudioPlayer.h
+++ b/include/com/amazonaws/kinesis/video/player/AudioPlayer.h
@@ -46,7 +46,7 @@ AudioPlayerHandle audioPlayerCreate(void);
* @param[in] handle Handle of AudioPlayer.
* @return AudioPlayerStatus Status of AudioPlayer.
*/
-AudioPlayerStatus audioPlayerGetStatus(const AudioPlayerHandle const handle);
+AudioPlayerStatus audioPlayerGetStatus(const AudioPlayerHandle handle);

/**
* @brief Get player capability.
@@ -55,7 +55,7 @@ AudioPlayerStatus audioPlayerGetStatus(const AudioPlayerHandle const handle);
* @param[out] pCapability Player capability.
* @return int 0 or error code.
*/
-int audioPlayerGetCapability(const AudioPlayerHandle const handle, AudioCapability* pCapability);
+int audioPlayerGetCapability(const AudioPlayerHandle handle, AudioCapability* pCapability);

/**
* @brief Set player format, channel number, bit depth and sample rate.
@@ -80,7 +80,7 @@ int audioPlayerSetFormat(AudioPlayerHandle handle, const AudioFormat format, con
* @param[in] pBitDepth Frame bit depth.
* @return int 0 or error code.
*/
-int audioPlayerGetFormat(const AudioPlayerHandle const handle, AudioFormat* pFormat, AudioChannel* pChannel, AudioSampleRate* pSampleRate,
+int audioPlayerGetFormat(const AudioPlayerHandle handle, AudioFormat* pFormat, AudioChannel* pChannel, AudioSampleRate* pSampleRate,
AudioBitDepth* pBitDepth);

/**
diff --git a/source/FILE/FILEAudioCapturer.c b/source/FILE/FILEAudioCapturer.c
index 8fb3e69..17d4ca2 100644
--- a/source/FILE/FILEAudioCapturer.c
+++ b/source/FILE/FILEAudioCapturer.c
@@ -84,7 +84,7 @@ AudioCapturerHandle audioCapturerCreate(void)
return (AudioCapturerHandle) fileHandle;
}

-AudioCapturerStatus audioCapturerGetStatus(const AudioCapturerHandle const handle)
+AudioCapturerStatus audioCapturerGetStatus(const AudioCapturerHandle handle)
{
if (!handle) {
return AUD_CAP_STATUS_NOT_READY;
@@ -94,7 +94,7 @@ AudioCapturerStatus audioCapturerGetStatus(const AudioCapturerHandle const handl
return fileHandle->status;
}

-int audioCapturerGetCapability(const AudioCapturerHandle const handle, AudioCapability* pCapability)
+int audioCapturerGetCapability(const AudioCapturerHandle handle, AudioCapability* pCapability)
{
FILE_HANDLE_NULL_CHECK(handle);
FILE_HANDLE_GET(handle);
@@ -170,7 +170,7 @@ int audioCapturerSetFormat(AudioCapturerHandle handle, const AudioFormat format,
return 0;
}

-int audioCapturerGetFormat(const AudioCapturerHandle const handle, AudioFormat* pFormat, AudioChannel* pChannel, AudioSampleRate* pSampleRate,
+int audioCapturerGetFormat(const AudioCapturerHandle handle, AudioFormat* pFormat, AudioChannel* pChannel, AudioSampleRate* pSampleRate,
AudioBitDepth* pBitDepth)
{
FILE_HANDLE_NULL_CHECK(handle);
diff --git a/source/FILE/FILEAudioPlayer.c b/source/FILE/FILEAudioPlayer.c
index 8f35381..2f18b77 100644
--- a/source/FILE/FILEAudioPlayer.c
+++ b/source/FILE/FILEAudioPlayer.c
@@ -33,12 +33,12 @@ AudioPlayerHandle audioPlayerCreate(void)
return NULL;
}

-AudioPlayerStatus audioPlayerGetStatus(const AudioPlayerHandle const handle)
+AudioPlayerStatus audioPlayerGetStatus(const AudioPlayerHandle handle)
{
return AUD_PLY_STATUS_NOT_READY;
}

-int audioPlayerGetCapability(const AudioPlayerHandle const handle, AudioCapability* pCapability)
+int audioPlayerGetCapability(const AudioPlayerHandle handle, AudioCapability* pCapability)
{
return -EAGAIN;
}
@@ -49,7 +49,7 @@ int audioPlayerSetFormat(AudioPlayerHandle handle, const AudioFormat format, con
return -EAGAIN;
}

-int audioPlayerGetFormat(const AudioPlayerHandle const handle, AudioFormat* pFormat, AudioChannel* pChannel, AudioSampleRate* pSampleRate,
+int audioPlayerGetFormat(const AudioPlayerHandle handle, AudioFormat* pFormat, AudioChannel* pChannel, AudioSampleRate* pSampleRate,
AudioBitDepth* pBitDepth)
{
return -EAGAIN;
diff --git a/source/FILE/FILEVideoCapturer.c b/source/FILE/FILEVideoCapturer.c
index 4054bb2..018c548 100644
--- a/source/FILE/FILEVideoCapturer.c
+++ b/source/FILE/FILEVideoCapturer.c
@@ -74,7 +74,7 @@ VideoCapturerHandle videoCapturerCreate(void)
return (VideoCapturerHandle) fileHandle;
}

-VideoCapturerStatus videoCapturerGetStatus(const VideoCapturerHandle const handle)
+VideoCapturerStatus videoCapturerGetStatus(const VideoCapturerHandle handle)
{
if (!handle) {
return VID_CAP_STATUS_NOT_READY;
@@ -84,7 +84,7 @@ VideoCapturerStatus videoCapturerGetStatus(const VideoCapturerHandle const handl
return fileHandle->status;
}

-int videoCapturerGetCapability(const VideoCapturerHandle const handle, VideoCapability* pCapability)
+int videoCapturerGetCapability(const VideoCapturerHandle handle, VideoCapability* pCapability)
{
FILE_HANDLE_NULL_CHECK(handle);
FILE_HANDLE_GET(handle);
@@ -132,7 +132,7 @@ int videoCapturerSetFormat(VideoCapturerHandle handle, const VideoFormat format,
return 0;
}

-int videoCapturerGetFormat(const VideoCapturerHandle const handle, VideoFormat* pFormat, VideoResolution* pResolution)
+int videoCapturerGetFormat(const VideoCapturerHandle handle, VideoFormat* pFormat, VideoResolution* pResolution)
{
FILE_HANDLE_NULL_CHECK(handle);
FILE_HANDLE_GET(handle);
2 changes: 1 addition & 1 deletion samples/kvsapp/kvsappcli.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ static void *audioThread(void *arg)
}
}

audioCapturerReleaseStream(videoCapturerHandle);
audioCapturerReleaseStream(audioCapturerHandle);
printf("audio thread leaving, err:%d\n", res);

return NULL;
Expand Down
7 changes: 7 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ set(CMAKE_C_FLAGS "-D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200112L ${CMAKE_C_FLAGS

set(LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR})

option(ENABLE_MKV_DUMP "Enable MKV dump to file" OFF)

set(LIB_SRC
${LIB_DIR}/include/kvs/kvsapp.h
${LIB_DIR}/include/kvs/kvsapp_options.h
Expand Down Expand Up @@ -98,6 +100,11 @@ if(${USE_WEBRTC_MBEDTLS_LIB})
target_include_directories(${LIB_NAME} PUBLIC ${WEBRTC_INC_PATH})
endif()

if(${ENABLE_MKV_DUMP})
message(STATUS "MKV dump enabled")
target_compile_definitions(${LIB_NAME} PUBLIC ENABLE_MKV_DUMP)
endif()

target_link_libraries(${LIB_NAME} PUBLIC
${LINK_LIBS}
)
Expand Down
27 changes: 16 additions & 11 deletions src/include/kvs/mkv_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,22 @@

#define MKV_TRACK_SIZE ( 2 )


#define MAX_TAG_AMOUNT 10
#define MAX_TAG_NAME_LEN 128
#define MAX_TAG_VALUE_LEN 256

//https://github.com/awslabs/amazon-kinesis-video-streams-pic/blob/c98c2a256a7bb3dfc4db41ae26d45e28ac7eec56/src/mkvgen/include/com/amazonaws/kinesis/video/mkvgen/Include.h#L99
//https://github.com/awslabs/amazon-kinesis-video-streams-pic/blob/c98c2a256a7bb3dfc4db41ae26d45e28ac7eec56/src/mkvgen/include/com/amazonaws/kinesis/video/mkvgen/Include.h#L104C31-L104C34

typedef struct {

char key[MAX_TAG_NAME_LEN];
char value[MAX_TAG_VALUE_LEN];

} MkvTag_t;


typedef struct {
uint8_t* buffer;
size_t size;
} MkvTagsBuffer_t;

typedef enum TrackType
{
Expand Down Expand Up @@ -229,12 +230,16 @@ int Mkv_generateAacCodecPrivateData(Mpeg4AudioObjectTypes_t objectType, uint32_t
*/
int Mkv_generatePcmCodecPrivateData(PcmFormatCode_t format, uint32_t uSamplingRate, uint16_t channels, uint8_t **ppCodecPrivateData, size_t *puCodecPrivateDataLen);



int Mkv_initializeTagsHdr(uint8_t *pTagHdr,
size_t uTagHdrLen,
uint32_t numTags,
const MkvTag_t *tags);

/**
* @brief Allocates and writes MKV tags with their headers to the buffer. The caller is responsible for freeing out->buffer using free().
*
* @param tagsList[in] the tags to write
* @param tagsListLen[in] length of tagsList
* @param out[out] buffer containing the bytes written and its length
* @return 0 on success, non-zero value otherwise
*
* @see MkvTag_t https://www.matroska.org/technical/elements.html
*/
int Mkv_generateTags(const MkvTag_t tagsList[], size_t tagsListLen, MkvTagsBuffer_t* out);

#endif /* KVS_MKV_GENERATOR_H */
15 changes: 15 additions & 0 deletions src/include/kvs/stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,21 @@ int Kvs_streamMemStatTotal(StreamHandle xStreamHandle, size_t *puMemTotal);
*/
int Kvs_dataFrameGetContent(DataFrameHandle xDataFrameHandle, uint8_t **ppMkvHeader, size_t *puMkvHeaderLen, uint8_t **ppData, size_t *puDataLen);

/**
* @brief Add MKV tags to the data frame
*
* @param xDataFrameHandle[in] The data frame handle
* @param tagsList[in] List of tags to add to this data frame
* @param tagsListLen[in] Length of the tagsList
* @param endOfStream[in] Whether to add the end of fragment tag (EOFR)
* @param ppMkvHeader[out] The MKV header
* @param puMkvHeaderLen[out] THe MKV header length
* @param ppData[out] The data pointer
* @param puDataLen[out] The data length
* @return 0 on success, non-zero value otherwise
*/
int Kvs_dataFrameAddTags(DataFrameHandle xDataFrameHandle, MkvTag_t* tagsList, size_t tagsListLen, bool endOfStream, uint8_t **ppMkvHeader, size_t *puMkvHeaderLen, uint8_t **ppData, size_t *puDataLen);

/**
* @brief Terminate a data frame handle
*
Expand Down
Loading