Skip to content

Commit b885357

Browse files
committed
Adding sample checks
1 parent 9e057c2 commit b885357

File tree

2 files changed

+153
-26
lines changed

2 files changed

+153
-26
lines changed

.github/workflows/samples.yml

Lines changed: 143 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,13 @@ jobs:
2121
args: -f sample.mp4
2222
- name: kvs_gstreamer_file_uploader_sample
2323
args: sample.mp4 0 audio-video
24-
# - name: kvs_gstreamer_multistream_sample
25-
# args: ""
2624
- name: kvs_gstreamer_sample
2725
args: sample.mp4
2826
- name: kvssink_gstreamer_sample
2927
args: sample.mp4
3028
runner:
31-
- id: macos-latest
32-
image: macos-latest
29+
- id: macos-13
30+
image: macos-13
3331

3432
- id: ubuntu-22.04
3533
image: ubuntu-latest
@@ -50,8 +48,9 @@ jobs:
5048

5149
env:
5250
AWS_KVS_LOG_LEVEL: 2
53-
KVS_DEBUG_DUMP_DATA_FILE_DIR: ./debug_output
51+
KVS_DEBUG_DUMP_DATA_FILE_DIR: ${{ github.workspace }}/build/debug_output
5452
DEBIAN_FRONTEND: noninteractive
53+
GST_PLUGIN_PATH: ${{ github.workspace }}/build
5554

5655
permissions:
5756
id-token: write
@@ -92,17 +91,14 @@ jobs:
9291
9392
- name: Build samples (Windows)
9493
if: runner.os == 'Windows'
95-
shell: cmd
9694
run: |
97-
@echo on
98-
set PATH=%PATH%;C:\Strawberry\perl\site\bin;C:\Strawberry\perl\bin;C:\Strawberry\c\bin;C:\Program Files\NASM;D:\a\amazon-kinesis-video-streams-producer-c\amazon-kinesis-video-streams-producer-c\open-source\lib;D:\a\amazon-kinesis-video-streams-producer-c\amazon-kinesis-video-streams-producer-c\open-source\bin
95+
$env:Path += ';C:\Strawberry\perl\site\bin;C:\Strawberry\perl\bin;C:\Strawberry\c\bin;C:\Program Files\NASM;D:\producer\open-source\local\lib;D:\producer\open-source\local\bin'
96+
mkdir D:\producer
97+
Move-Item -Path "D:\a\amazon-kinesis-video-streams-producer-sdk-cpp\amazon-kinesis-video-streams-producer-sdk-cpp\*" -Destination "D:\producer"
98+
cd D:\producer
9999
git config --system core.longpaths true
100-
"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
101-
mkdir build
102-
cd build
103-
cmake -G "NMake Makefiles" -DBUILD_GSTREAMER_PLUGIN=ON -DPKG_CONFIG_EXECUTABLE="D:\\gstreamer\\1.0\\msvc_x86_64\\bin\\pkg-config.exe" ..
104-
nmake
105-
mkdir "%KVS_DEBUG_DUMP_DATA_FILE_DIR%"
100+
dir
101+
.github\build_windows.bat
106102
107103
- name: Configure AWS Credentials
108104
uses: aws-actions/configure-aws-credentials@v4
@@ -114,9 +110,6 @@ jobs:
114110

115111
- name: Run ${{ matrix.sample.name }} (Linux & Mac)
116112
if: runner.os == 'Linux' || runner.os == 'macOS'
117-
env:
118-
GST_PLUGIN_PATH: ${{ github.workspace }}/build
119-
KVS_DEBUG_DUMP_DATA_FILE_DIR: ${{ github.workspace }}/build/debug_output
120113
working-directory: ./build
121114
run: |
122115
curl -fsSL -o sample.mp4 https://awsj-iot-handson.s3-ap-northeast-1.amazonaws.com/kvs-workshop/sample.mp4
@@ -125,15 +118,21 @@ jobs:
125118
- name: Run ${{ matrix.sample.name }} (Windows)
126119
if: runner.os == 'Windows'
127120
env:
128-
GST_PLUGIN_PATH: ${{ github.workspace }}/build
129-
KVS_DEBUG_DUMP_DATA_FILE_DIR: ${{ github.workspace }}/build/debug_output
130-
working-directory: ./build
121+
GST_PLUGIN_PATH: D:\producer\build
122+
KVS_DEBUG_DUMP_DATA_FILE_DIR: D:\producer\debug_output
123+
working-directory: D:\producer\build
131124
run: |
125+
# Equivalent to set -x
126+
Set-PSDebug -Trace 1
127+
132128
$env:Path += ';C:\Strawberry\perl\site\bin;C:\Strawberry\perl\bin;C:\Strawberry\c\bin;C:\Program Files\NASM;D:\producer\open-source\local\lib;D:\producer\open-source\local\bin;D:\gstreamer\1.0\msvc_x86_64\bin'
133129
130+
mkdir D:\producer\debug_output
131+
134132
Invoke-WebRequest -Uri https://awsj-iot-handson.s3-ap-northeast-1.amazonaws.com/kvs-workshop/sample.mp4 -OutFile sample.mp4
135-
$exePath = Join-Path $PWD ${{ matrix.sample.name }}
136-
& $exePath.exe demo-stream-producer-cpp-${{ matrix.runner.id }}-ci-${{ matrix.sample.name }} ${{ matrix.sample.args }}
133+
dir
134+
$exePath = Join-Path $PWD ${{ matrix.sample.name }}.exe
135+
& $exePath demo-stream-producer-cpp-${{ matrix.runner.id }}-ci-${{ matrix.sample.name }} ${{ matrix.sample.args }}
137136
138137
- name: Verify MKV dump (Mac & Linux)
139138
if: runner.os == 'Linux' || runner.os == 'macOS'
@@ -154,13 +153,13 @@ jobs:
154153
done
155154
shell: bash
156155

157-
- name: Verify MKV dump
156+
- name: Verify MKV dump (Windows)
158157
if: runner.os == 'Windows'
159158
working-directory: D:\producer\build
160159
run: |
161160
$env:Path += ";C:\Program Files\MKVToolNix"
162-
dir debug_output
163-
$mkvFiles = Get-ChildItem -Path "D:\producer\build\debug_output" -Filter *.mkv
161+
dir D:\producer\debug_output
162+
$mkvFiles = Get-ChildItem -Path "D:\producer\debug_output" -Filter *.mkv
164163
if ($mkvFiles.Count -eq 0) {
165164
Write-Error "No MKV files found in D:\producer\build\debug_output"
166165
exit 1
@@ -170,3 +169,122 @@ jobs:
170169
Write-Output "Verifying $($file.FullName) with mkvinfo (verbose and hexdump):"
171170
mkvinfo.exe -v -X "$($file.FullName)"
172171
}
172+
173+
multistream-sample:
174+
name: Multistream sample on Mac
175+
runs-on: macos-13
176+
timeout-minutes: 30
177+
178+
env:
179+
AWS_KVS_LOG_LEVEL: 2
180+
KVS_DEBUG_DUMP_DATA_FILE_DIR: ${{ github.workspace }}/build/debug_output
181+
GST_PLUGIN_PATH: ${{ github.workspace }}/build
182+
DEBIAN_FRONTEND: noninteractive
183+
184+
permissions:
185+
id-token: write
186+
contents: read
187+
188+
steps:
189+
- name: Clone repository
190+
uses: actions/checkout@v4
191+
192+
- name: Install dependencies
193+
run: |
194+
brew install gstreamer log4cplus mkvtoolnix coreutils
195+
brew install --cask docker
196+
197+
- name: Build samples
198+
run: |
199+
mkdir build && cd build
200+
mkdir -p $KVS_DEBUG_DUMP_DATA_FILE_DIR
201+
cmake .. -DBUILD_GSTREAMER_PLUGIN=ON -DBUILD_DEPENDENCIES=OFF
202+
make -j$(nproc)
203+
204+
- name: Configure AWS Credentials
205+
uses: aws-actions/configure-aws-credentials@v4
206+
with:
207+
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
208+
role-session-name: ${{ secrets.AWS_ROLE_SESSION_NAME }}
209+
aws-region: ${{ secrets.AWS_REGION }}
210+
role-duration-seconds: 10800
211+
212+
- name: Run multistream sample
213+
working-directory: ./build
214+
run: |
215+
set -x
216+
217+
open -a /Applications/Docker.app --args --unattended --accept-license
218+
echo "We are waiting for Docker to be up and running. It can take over 2 minutes..."
219+
while ! /Applications/Docker.app/Contents/Resources/bin/docker info &>/dev/null; do sleep 1; done
220+
221+
sudo ln -s ~/.docker/run/docker.sock /var/run/docker.sock
222+
223+
docker run -d --rm -it -e RTSP_PROTOCOLS=tcp -p 8554:8554 bluenviron/mediamtx:latest
224+
docker run -d --rm -it -e RTSP_PROTOCOLS=tcp -p 8555:8554 bluenviron/mediamtx:latest
225+
226+
(
227+
ffmpeg -re -f lavfi -i "testsrc=size=640x480:rate=10" -vcodec libx264 -x264-params keyint=25 -f rtsp rtsp://localhost:8554/mystream
228+
) &
229+
(
230+
ffmpeg -re -f lavfi -i "testsrc=size=640x480:rate=10" -vcodec libx264 -x264-params keyint=25 -f rtsp rtsp://localhost:8555/mystream
231+
) &
232+
233+
echo "rtsp://0.0.0.0:8554/mystream" > rtsp-urls.txt
234+
echo "rtsp://0.0.0.0:8555/mystream" >> rtsp-urls.txt
235+
236+
sleep 10
237+
gst-discoverer-1.0 rtsp://0.0.0.0:8554/mystream
238+
gst-discoverer-1.0 rtsp://0.0.0.0:8555/mystream
239+
240+
set +e # Disable exit on error for the timeout command
241+
gtimeout --preserve-status --signal=SIGINT --kill-after=15s 30s \
242+
./kvs_gstreamer_multistream_sample demo-stream-producer-cpp-macos-13-ci-kvs_gstreamer_multistream_sample rtsp-urls.txt
243+
EXIT_CODE=$?
244+
set -e # Re-enable exit on error
245+
246+
# 130 (128 + 2): Process killed by SIGINT
247+
# 137: Process killed by SIGKILL (if the --kill-after timeout is reached)
248+
echo "Command exited with code: $EXIT_CODE"
249+
if [ $EXIT_CODE -ne 130 ]; then
250+
echo "Command did not exit gracefully after interrupt."
251+
exit 1
252+
fi
253+
254+
shell: bash
255+
256+
- name: Verify MKV dump
257+
working-directory: ./build/debug_output
258+
run: |
259+
shopt -s nullglob # Ensure globbing works correctly and avoids errors when no files are found
260+
261+
ls -tlrh
262+
mkvfiles=(*.mkv)
263+
if [ ${#mkvfiles[@]} -eq 0 ]; then
264+
echo "No MKV files found in debug_output"
265+
exit 1
266+
fi
267+
268+
found_0=0
269+
found_1=0
270+
271+
for file in "${mkvfiles[@]}"; do
272+
if [[ "$file" == demo-stream-producer-cpp-macos-13-ci-kvs_gstreamer_multistream_sample_0* ]]; then
273+
found_0=1
274+
elif [[ "$file" == demo-stream-producer-cpp-macos-13-ci-kvs_gstreamer_multistream_sample_1* ]]; then
275+
found_1=1
276+
fi
277+
done
278+
279+
if [ $found_0 -eq 0 ] || [ $found_1 -eq 0 ]; then
280+
echo "Expected at least one file starting with each prefix:"
281+
echo " - demo-stream-producer-cpp-macos-13-ci-kvs_gstreamer_multistream_sample_0"
282+
echo " - demo-stream-producer-cpp-macos-13-ci-kvs_gstreamer_multistream_sample_1"
283+
exit 1
284+
fi
285+
286+
for file in "${mkvfiles[@]}"; do
287+
echo "Verifying $file with mkvinfo (verbose and hexdump):"
288+
mkvinfo -v -X "$file"
289+
done
290+
shell: bash

samples/kvs_gstreamer_multistream_sample.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ LOGGER_TAG("com.amazonaws.kinesis.video.gstreamer");
5353
#define DEFAULT_BUFFER_SIZE (1 * 1024 * 1024)
5454
#define DEFAULT_STORAGE_SIZE (128 * 1024 * 1024)
5555
#define DEFAULT_ROTATION_TIME_SECONDS 3600
56+
#define DEFAULT_FRAME_DURATION_MS 2
5657

5758
namespace com { namespace amazonaws { namespace kinesis { namespace video {
5859

@@ -180,6 +181,7 @@ typedef struct _CustomData {
180181
// Pts of first frame
181182
map<string, uint64_t> first_pts_map;
182183
map<string, uint64_t> producer_start_time_map;
184+
map<string, uint64_t> last_dts_map;
183185
} CustomData;
184186

185187
void create_kinesis_video_frame(Frame *frame, const nanoseconds &pts, const nanoseconds &dts, FRAME_FLAGS flags,
@@ -259,6 +261,12 @@ static GstFlowReturn on_new_sample(GstElement *sink, CustomData *data) {
259261

260262
buffer->pts += data->producer_start_time_map[stream_handle_key] - data->first_pts_map[stream_handle_key];
261263

264+
if (!GST_BUFFER_DTS_IS_VALID(buffer)) {
265+
buffer->dts = data->last_dts_map[stream_handle_key] + DEFAULT_FRAME_DURATION_MS * HUNDREDS_OF_NANOS_IN_A_MILLISECOND * DEFAULT_TIME_UNIT_IN_NANOS;
266+
}
267+
268+
data->last_dts_map[stream_handle_key] = buffer->dts;
269+
262270
if (false == put_frame(data->kinesis_video_stream_handles[stream_handle_key], data->frame_data_map[stream_handle_key], buffer_size, std::chrono::nanoseconds(buffer->pts),
263271
std::chrono::nanoseconds(buffer->dts), kinesis_video_flags)) {
264272
GST_WARNING("Dropped frame");
@@ -405,7 +413,8 @@ int gstreamer_init(int argc, char *argv[]) {
405413
data.frame_data_map = map<string, uint8_t*>();
406414
data.frame_data_size_map = map<string, UINT32>();
407415
data.first_pts_map = map<string, uint64_t>();
408-
data.producer_start_time_map = map<string, uint64_t>();;
416+
data.producer_start_time_map = map<string, uint64_t>();
417+
data.last_dts_map = map<string, uint64_t>();;
409418

410419
/* init GStreamer */
411420
gst_init(&argc, &argv);

0 commit comments

Comments
 (0)