Skip to content

Commit

Permalink
encoder: output: Fix bug where network output was not routed through …
Browse files Browse the repository at this point in the history
…libav on Pi 5

If the --codec libav option is not set, and a network stream output is
specified, the NetOutput class will be initialised together with libav
and fail to work on a Pi 5.

Fix this by ensuring if we are going to use libav, do not initialise the
NetOutput class, and allow libav to handle the network output.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
  • Loading branch information
naushir committed Jan 30, 2024
1 parent 0bcbaaf commit 9ae39f8
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 16 deletions.
2 changes: 2 additions & 0 deletions apps/rpicam_raw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ int main(int argc, char *argv[])
VideoOptions *options = app.GetOptions();
if (options->Parse(argc, argv))
{
// Disable any codec (h.264/libav) based operations.
options->codec = "yuv420";
options->denoise = "cdn_off";
options->nopreview = true;
if (options->verbose >= 2)
Expand Down
26 changes: 11 additions & 15 deletions encoder/encoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include "libav_encoder.hpp"
#endif

Encoder *h264_codec_select(VideoOptions *options, const StreamInfo &info)
bool bcm2835_encoder_available()
{
const char hw_codec[] = "/dev/video11";
struct v4l2_capability caps;
Expand All @@ -32,8 +32,15 @@ Encoder *h264_codec_select(VideoOptions *options, const StreamInfo &info)
int ret = ioctl(fd, VIDIOC_QUERYCAP, &caps);
close(fd);
if (!ret && !strncmp((char *)caps.card, "bcm2835-codec-encode", sizeof(caps.card)))
return new H264Encoder(options, info);
return true;
}
return false;
}

static Encoder *h264_codec_select(VideoOptions *options, const StreamInfo &info)
{
if (bcm2835_encoder_available())
return new H264Encoder(options, info);

#if LIBAV_PRESENT
// No hardware codec available, use x264 through libav.
Expand All @@ -45,26 +52,15 @@ Encoder *h264_codec_select(VideoOptions *options, const StreamInfo &info)
}

#if LIBAV_PRESENT
Encoder *libav_codec_select(VideoOptions *options, const StreamInfo &info)
static Encoder *libav_codec_select(VideoOptions *options, const StreamInfo &info)
{
if (options->libav_video_codec == "h264_v4l2m2m")
{
const char hw_codec[] = "/dev/video11";
struct v4l2_capability caps;
memset(&caps, 0, sizeof(caps));
int fd = open(hw_codec, O_RDWR, 0);
if (fd)
{
int ret = ioctl(fd, VIDIOC_QUERYCAP, &caps);
close(fd);
if (!ret && !strncmp((char *)caps.card, "bcm2835-codec-encode", sizeof(caps.card)))
if (bcm2835_encoder_available())
return new LibAvEncoder(options, info);
}

// No h264_v4l2m2m libav codec available, use libx264 if nothing else is provided.
options->libav_video_codec = "libx264";
}

return new LibAvEncoder(options, info);
}
#endif
Expand Down
4 changes: 3 additions & 1 deletion output/output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "net_output.hpp"
#include "output.hpp"

extern bool bcm2835_encoder_available();

Output::Output(VideoOptions const *options)
: options_(options), fp_timestamps_(nullptr), state_(WAITING_KEYFRAME), time_offset_(0), last_timestamp_(0),
buf_metadata_(std::cout.rdbuf()), of_metadata_()
Expand Down Expand Up @@ -101,7 +103,7 @@ void Output::outputBuffer(void *mem, size_t size, int64_t timestamp_us, uint32_t

Output *Output::Create(VideoOptions const *options)
{
if (options->codec == "libav")
if (options->codec == "libav" || (options->codec == "h264" && !bcm2835_encoder_available()))
return new Output(options);

if (strncmp(options->output.c_str(), "udp://", 6) == 0 || strncmp(options->output.c_str(), "tcp://", 6) == 0)
Expand Down

0 comments on commit 9ae39f8

Please sign in to comment.