diff --git a/encoder/encoder.cpp b/encoder/encoder.cpp index a0622ed1..05fe3dd4 100644 --- a/encoder/encoder.cpp +++ b/encoder/encoder.cpp @@ -6,6 +6,11 @@ */ #include +#include +#include +#include + +#include #include "encoder.hpp" #include "h264_encoder.hpp" @@ -16,12 +21,34 @@ #include "libav_encoder.hpp" #endif -Encoder *Encoder::Create(VideoOptions const *options, const StreamInfo &info) +Encoder *h264_codec_select(VideoOptions *options, const StreamInfo &info) +{ + 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); + if (!ret && !strncmp((char *)caps.card, "bcm2835-codec-encode", sizeof(caps.card))) + return new H264Encoder(options, info); + } + +#if LIBAV_PRESENT + // No hardware codec available, use x264 through libav. + options->libav_video_codec = "libx264"; + return new LibAvEncoder(options, info); +#endif + + throw std::runtime_error("Unable to find an appropriate H.264 codec"); +} + +Encoder *Encoder::Create(VideoOptions *options, const StreamInfo &info) { if (strcasecmp(options->codec.c_str(), "yuv420") == 0) return new NullEncoder(options); else if (strcasecmp(options->codec.c_str(), "h264") == 0) - return new H264Encoder(options, info); + return h264_codec_select(options, info); #if LIBAV_PRESENT else if (strcasecmp(options->codec.c_str(), "libav") == 0) return new LibAvEncoder(options, info); diff --git a/encoder/encoder.hpp b/encoder/encoder.hpp index 192f09c5..fda6e025 100644 --- a/encoder/encoder.hpp +++ b/encoder/encoder.hpp @@ -18,7 +18,7 @@ typedef std::function OutputReadyCallback; class Encoder { public: - static Encoder *Create(VideoOptions const *options, StreamInfo const &info); + static Encoder *Create(VideoOptions *options, StreamInfo const &info); Encoder(VideoOptions const *options) : options_(options) {} virtual ~Encoder() {}