Skip to content
Open
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
9 changes: 5 additions & 4 deletions .github/ci/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ARG DOCKER_ARCH
ARG DEBIAN_VERSION
ARG DOCKER_REPO
FROM --platform=linux/${DOCKER_ARCH} ${DOCKER_REPO}debian:${DEBIAN_VERSION} as build_env
FROM --platform=linux/${DOCKER_ARCH} ${DOCKER_REPO}debian:${DEBIAN_VERSION} AS build_env

RUN apt-get -y update && apt-get -y install gnupg2

Expand All @@ -11,8 +11,9 @@ ARG BUILD_TYPE="generic"
RUN [ "$BUILD_TYPE" != "raspi" ] || \
( \
( [ "$(dpkg --print-architecture)" != "armhf" ] || echo "deb http://raspbian.raspberrypi.org/raspbian/ $DEBIAN_VERSION main contrib non-free rpi" > /etc/apt/sources.list ) && \
gpg --keyserver keyserver.ubuntu.com --recv-keys 9165938D90FDDD2E 82B129927FA3303E && \
gpg --export 9165938D90FDDD2E 82B129927FA3303E > /etc/apt/trusted.gpg.d/raspi.gpg && \
echo "deb http://archive.raspberrypi.org/debian/ $DEBIAN_VERSION main" > /etc/apt/sources.list.d/raspi.list && \
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 9165938D90FDDD2E 82B129927FA3303E && \
apt-get -y update && \
apt-get -y install libcamera-dev liblivemedia-dev \
)
Expand All @@ -21,14 +22,14 @@ RUN [ "$BUILD_TYPE" != "raspi" ] || \
RUN apt-get -y install build-essential xxd cmake ccache git-core pkg-config \
libavformat-dev libavutil-dev libavcodec-dev libssl-dev v4l-utils debhelper

FROM build_env as build
FROM build_env AS build
ADD / /src
WORKDIR /src
RUN git clean -ffdx
RUN git submodule update --init --recursive --recommend-shallow
RUN git submodule foreach --recursive git clean -ffdx

FROM build as deb_make
FROM build AS deb_make
ARG GIT_VERSION
ARG BUILD_TYPE="generic"
ENV DEB_BUILD_PROFILES="$BUILD_TYPE"
Expand Down
6 changes: 6 additions & 0 deletions .github/ci/arm32-cross
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

apt install -y g{cc,++}-arm-linux-gnueabihf
export CC=arm-linux-gnueabihf-gcc
export CXX=arm-linux-gnueabihf-g++
exec "$@"
39 changes: 32 additions & 7 deletions .github/ci/build-env
Original file line number Diff line number Diff line change
@@ -1,20 +1,44 @@
#!/bin/bash

if [[ $# -lt 3 ]]; then
echo "usage: $0 <generic|raspi> <bullseye|bookworm> <amd64|arm32v7|arm64v8>"
if [[ $# -lt 2 ]]; then
echo "usage: $0 <generic|raspi> <bullseye|bookworm> [amd64|arm32v7|arm64v8] [cmdline args]"
exit 1
fi

docker_image="camera_streamer_build_env"

build_type="raspi"
[[ -n "$1" ]] && build_type="$1"
shift

debian_version="bookworm"
[[ -n "$2" ]] && debian_version="$2" && docker_image="${docker_image}_${2}"

docker_arch=""
[[ -n "$3" ]] && docker_arch="$3" && docker_image="${docker_image}_${3}"
[[ -n "$1" ]] && debian_version="$1" && docker_image="${docker_image}_${1}"
shift

arch=${1:-$(dpkg --print-architecture)}
shift

case "$arch" in
amd64)
docker_arch="amd64"
docker_repo="amd64/"
;;

armhf|arm32v7)
docker_arch="arm/v7"
docker_repo="arm32v7/"
;;

arm64|arm64v8)
docker_arch="arm64/v8"
docker_repo="arm64v8/"
;;

*)
echo "Unsupported architecture: $arch"
exit 1
;;
esac

PWD=$(pwd)
ROOT=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )/../.." &> /dev/null && pwd)
Expand All @@ -23,8 +47,9 @@ set -xeo pipefail

DOCKER_BUILDKIT=1 docker build -t "$docker_image" \
--build-arg "DOCKER_ARCH=$docker_arch" \
--build-arg "DOCKER_REPO=$docker_repo" \
--build-arg "DEBIAN_VERSION=$debian_version" \
--build-arg "BUILD_TYPE=$build_type" \
--target build_env - < .github/ci/Dockerfile

exec docker run --rm -it -u "$UID" -e "CCACHE_DIR=$ROOT/tmp/ccache" -v "$ROOT:$ROOT" -w "$ROOT" "$docker_image"
exec docker run --rm -it -u "$UID" -e "CCACHE_DIR=$ROOT/tmp/ccache" -v "$ROOT:$ROOT" -w "$ROOT" "$docker_image" "$@"
2 changes: 1 addition & 1 deletion .github/workflows/build_release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
contents: write
strategy:
matrix:
debian_version: [bullseye, bookworm]
debian_version: [bullseye, bookworm, trixie]
arch:
- docker: amd64
runner: ubuntu-24.04
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
strategy:
fail-fast: false
matrix:
debian_version: [bullseye, bookworm]
debian_version: [bullseye, bookworm, trixie]
arch:
- docker: amd64
variant: amd64
Expand Down
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ CFLAGS += -Wno-error=cpp

# LOG_*(this, ...)
CFLAGS += -Wno-error=nonnull-compare
CFLAGS += -Wno-nonnull-compare

# libdatachannel deprecations on bookworm
# error: 'HMAC_Init_ex' is deprecated: Since OpenSSL 3.0
Expand All @@ -24,6 +25,7 @@ CCACHE ?= ccache
endif

LIBDATACHANNEL_PATH ?= third_party/libdatachannel
LIBDATACHANNEL_VERSION ?= $(LIBDATACHANNEL_PATH)/v0.23.222529eb2c8ae44

USE_HW_H264 ?= 1
USE_FFMPEG ?= $(shell pkg-config libavutil libavformat libavcodec && echo 1)
Expand Down Expand Up @@ -116,6 +118,10 @@ html/%.c: html/%
xxd -i $< > [email protected]
mv [email protected] $@

$(LIBDATACHANNEL_PATH)/build/libdatachannel-static.a: $(LIBDATACHANNEL_PATH)
$(LIBDATACHANNEL_VERSION):

$(LIBDATACHANNEL_PATH)/build/libdatachannel-static.a: $(LIBDATACHANNEL_PATH) $(LIBDATACHANNEL_VERSION)
git submodule update --init --recursive $(LIBDATACHANNEL_PATH)
[ -e $</build/Makefile ] || cmake -S $< -B $</build
$(MAKE) -C $</build datachannel-static
touch $(LIBDATACHANNEL_VERSION) $@
5 changes: 3 additions & 2 deletions device/dummy/buffer_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "util/opts/log.h"

#include <stdlib.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>

Expand Down Expand Up @@ -36,12 +37,12 @@ int dummy_buffer_list_open(buffer_list_t *buf_list)

buf_list->dummy->data = malloc(st.st_size);
if (!buf_list->dummy->data) {
LOG_ERROR(buf_list, "Can't allocate %ld bytes for %s", st.st_size, buf_list->dev->path);
LOG_ERROR(buf_list, "Can't allocate %" PRId64 " bytes for %s", (off64_t)st.st_size, buf_list->dev->path);
}

buf_list->dummy->length = read(fd, buf_list->dummy->data, st.st_size);
if (!buf_list->dummy->data) {
LOG_ERROR(buf_list, "Can't read %ld bytes for %s. Only read %zu.", st.st_size, buf_list->dev->path, buf_list->dummy->length);
LOG_ERROR(buf_list, "Can't read %" PRId64 " bytes for %s. Only read %zu.", (off64_t)st.st_size, buf_list->dev->path, buf_list->dummy->length);
}

close(fd);
Expand Down
2 changes: 1 addition & 1 deletion output/http_ffmpeg.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ static int http_ffmpeg_read_from_buf(void *opaque, uint8_t *buf, int buf_size)
return buf_size;
}

static int http_ffmpeg_write_to_stream(void *opaque, uint8_t *buf, int buf_size)
static int http_ffmpeg_write_to_stream(void *opaque, const uint8_t *buf, int buf_size)
{
http_ffmpeg_status_t *status = opaque;
if (!status->stream)
Expand Down
28 changes: 4 additions & 24 deletions output/webrtc/webrtc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ extern "C" {
#include <rtc/peerconnection.hpp>
#include <rtc/rtcpsrreporter.hpp>
#include <rtc/h264rtppacketizer.hpp>
#include <rtc/h264packetizationhandler.hpp>
#include <rtc/rtcpnackresponder.hpp>

#include "third_party/magic_enum/include/magic_enum.hpp"
Expand Down Expand Up @@ -63,23 +62,6 @@ struct ClientTrackData

void startStreaming()
{
double currentTime_s = get_monotonic_time_us(NULL, NULL)/(1000.0*1000.0);
sender->rtpConfig->setStartTime(currentTime_s, rtc::RtpPacketizationConfig::EpochStart::T1970);
sender->startRecording();
}

void sendTime()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not remove sendTime. If you remove it, WebRTC won't work and the client will only show the keyframes.

{
double currentTime_s = get_monotonic_time_us(NULL, NULL)/(1000.0*1000.0);

auto rtpConfig = sender->rtpConfig;
uint32_t elapsedTimestamp = rtpConfig->secondsToTimestamp(currentTime_s);

sender->rtpConfig->timestamp = sender->rtpConfig->startTimestamp + elapsedTimestamp;
auto reportElapsedTimestamp = sender->rtpConfig->timestamp - sender->previousReportedTimestamp;
if (sender->rtpConfig->timestampToSeconds(reportElapsedTimestamp) > 1) {
sender->setNeedsToReport();
}
}

bool wantsFrame() const
Expand Down Expand Up @@ -176,7 +158,6 @@ class Client
}

rtc::binary data((std::byte*)buf->start, (std::byte*)buf->start + buf->used);
video->sendTime();
video->track->send(data);
}

Expand Down Expand Up @@ -249,14 +230,13 @@ static std::shared_ptr<ClientTrackData> webrtc_add_video(const std::shared_ptr<r
video.setBitrate(1000);
video.addSSRC(ssrc, cname, msid, cname);
auto track = pc->addTrack(video);
auto rtpConfig = std::make_shared<rtc::RtpPacketizationConfig>(ssrc, cname, payloadType, rtc::H264RtpPacketizer::defaultClockRate);
auto rtpConfig = std::make_shared<rtc::RtpPacketizationConfig>(ssrc, cname, payloadType, rtc::H264RtpPacketizer::ClockRate);
auto packetizer = std::make_shared<rtc::H264RtpPacketizer>(rtc::H264RtpPacketizer::Separator::LongStartSequence, rtpConfig);
auto h264Handler = std::make_shared<rtc::H264PacketizationHandler>(packetizer);
auto srReporter = std::make_shared<rtc::RtcpSrReporter>(rtpConfig);
h264Handler->addToChain(srReporter);
packetizer->addToChain(srReporter);
auto nackResponder = std::make_shared<rtc::RtcpNackResponder>();
h264Handler->addToChain(nackResponder);
track->setMediaHandler(h264Handler);
packetizer->addToChain(nackResponder);
track->setMediaHandler(packetizer);
return std::shared_ptr<ClientTrackData>(new ClientTrackData{track, srReporter});
}

Expand Down
2 changes: 1 addition & 1 deletion third_party/libdatachannel
Submodule libdatachannel updated 246 files
14 changes: 10 additions & 4 deletions util/ffmpeg/remuxer.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@
static AVRational time_base = {1, 1000LL * 1000LL};
static unsigned avio_ctx_buffer_size = 4096;

static int ffmpeg_remuxer_init_avcontext(AVFormatContext **context, ffmpeg_remuxer_t *remuxer, int output, int (*packet)(void *opaque, uint8_t *buf, int buf_size))
#if LIBAVFORMAT_VERSION_MAJOR < 61
typedef int (*ffmpeg_write_nonconst_packet)(void *opaque, uint8_t *buf, int buf_size);
#else // LIBAVFORMAT_VERSION_MAJOR < 61
#define ffmpeg_write_nonconst_packet ffmpeg_write_packet
#endif // LIBAVFORMAT_VERSION_MAJOR < 61

static int ffmpeg_remuxer_init_avcontext(AVFormatContext **context, ffmpeg_remuxer_t *remuxer, int output, ffmpeg_write_packet packet_out, ffmpeg_read_packet packet_in)
{
uint8_t *buffer = NULL;
AVIOContext *avio = NULL;
Expand All @@ -20,7 +26,7 @@ static int ffmpeg_remuxer_init_avcontext(AVFormatContext **context, ffmpeg_remux
buffer = av_malloc(buffer_size);
if (!buffer)
return AVERROR(ENOMEM);
avio = avio_alloc_context(buffer, buffer_size, output, remuxer->opaque, output ? NULL : packet, output ? packet : NULL, NULL);
avio = avio_alloc_context(buffer, buffer_size, output, remuxer->opaque, packet_in, (ffmpeg_write_nonconst_packet)packet_out, NULL);
if (!avio)
goto error;
if (output && (ret = avformat_alloc_output_context2(context, NULL, remuxer->video_format, NULL)) < 0)
Expand Down Expand Up @@ -106,9 +112,9 @@ int ffmpeg_remuxer_open(ffmpeg_remuxer_t *remuxer)
remuxer->packet = av_packet_alloc();
if (!remuxer->packet)
return AVERROR(ENOMEM);
if ((ret = ffmpeg_remuxer_init_avcontext(&remuxer->input_context, remuxer, 0, remuxer->read_packet)) < 0)
if ((ret = ffmpeg_remuxer_init_avcontext(&remuxer->input_context, remuxer, 0, NULL, remuxer->read_packet)) < 0)
return ret;
if ((ret = ffmpeg_remuxer_init_avcontext(&remuxer->output_context, remuxer, 1, remuxer->write_packet)) < 0)
if ((ret = ffmpeg_remuxer_init_avcontext(&remuxer->output_context, remuxer, 1, remuxer->write_packet, NULL)) < 0)
return ret;
if ((ret = avformat_open_input(&remuxer->input_context, NULL, input_format, &remuxer->input_opts)) < 0)
return ret;
Expand Down
7 changes: 4 additions & 3 deletions util/ffmpeg/remuxer.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@
#define FFMPEG_DATA_PACKET_EOF -1
#endif

typedef int (*ffmpeg_data_packet)(void *opaque, uint8_t *buf, int buf_size);
typedef int (*ffmpeg_read_packet)(void *opaque, uint8_t *buf, int buf_size);
typedef int (*ffmpeg_write_packet)(void *opaque, const uint8_t *buf, int buf_size);

typedef struct ffmpeg_remuxer_s {
const char *name;
const char *input_format;
const char *video_format;
void *opaque;
ffmpeg_data_packet read_packet;
ffmpeg_data_packet write_packet;
ffmpeg_read_packet read_packet;
ffmpeg_write_packet write_packet;
unsigned read_buffer_size;
unsigned write_buffer_size;

Expand Down
Loading