qTox
Version: nightly | Commit: bc751c8e1cac455f9690654fcfe0f560d2d7dfdd
|
Go to the documentation of this file.
21 #pragma GCC diagnostic push
22 #pragma GCC diagnostic ignored "-Wold-style-cast"
23 #include <libavcodec/avcodec.h>
24 #include <libavdevice/avdevice.h>
25 #include <libavformat/avformat.h>
26 #include <libswscale/swscale.h>
27 #pragma GCC diagnostic pop
34 #include <QReadLocker>
35 #include <QWriteLocker>
36 #include <QtConcurrent/QtConcurrentRun>
96 : deviceThread{
new QThread}
102 #if LIBAVCODEC_VERSION_INT < 3747941
105 , videoStreamIndex{-1}
109 qRegisterMetaType<VideoMode>(
"VideoMode");
110 deviceThread->setObjectName(
"Device thread");
111 deviceThread->start();
112 moveToThread(deviceThread);
117 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 9, 100)
120 avdevice_register_all();
165 QMetaObject::invokeMethod(
this,
"setupDevice", Q_ARG(
const QString&, DeviceName),
216 avcodec_free_context(&
cctx);
218 #if LIBAVCODEC_VERSION_INT < 3747941
235 QThread::yieldCurrentThread();
263 QMetaObject::invokeMethod(
this,
"openDevice");
284 qWarning() <<
"Failed to open device!";
298 #if LIBAVCODEC_VERSION_INT < 3747941
303 if (type == AVMEDIA_TYPE_VIDEO) {
310 qWarning() <<
"Video stream not found";
316 #if LIBAVCODEC_VERSION_INT < 3747941
322 codecId = cparams->codec_id;
324 const AVCodec* codec = avcodec_find_decoder(codecId);
326 qWarning() <<
"Codec not found";
332 #if LIBAVCODEC_VERSION_INT < 3747941
334 cctx = avcodec_alloc_context3(codec);
336 qWarning() <<
"Can't copy context";
341 cctx->refcounted_frames = 1;
344 cctx = avcodec_alloc_context3(codec);
345 if (avcodec_parameters_to_context(
cctx, cparams) < 0) {
346 qWarning() <<
"Can't create AV context from parameters";
353 if (avcodec_open2(
cctx, codec,
nullptr) < 0) {
354 qWarning() <<
"Can't open codec";
355 avcodec_free_context(&
cctx);
361 qDebug() <<
"The stream thread is already running! Keeping the current one open.";
367 QThread::yieldCurrentThread();
379 QMetaObject::invokeMethod(
this,
"closeDevice");
395 avcodec_free_context(&
cctx);
396 #if LIBAVCODEC_VERSION_INT < 3747941
411 auto streamLoop = [=]() {
417 #if LIBAVCODEC_VERSION_INT < 3747941
418 AVFrame* frame = av_frame_alloc();
427 avcodec_decode_video2(
cctx, frame, &frameFinished, &packet);
428 if (!frameFinished) {
439 bool readyToRecive = isVideo && !avcodec_send_packet(
cctx, &packet);
442 AVFrame* frame = av_frame_alloc();
443 if (frame && !avcodec_receive_frame(
cctx, frame)) {
447 av_frame_free(&frame);
452 av_packet_unref(&packet);
void open()
Opens the device again. Never fails.
void setupDefault()
Setup default device.
void unsubscribe() override
Stop emitting frameAvailable signals, and free associated resources if necessary.
static CameraSource * instance
AVCodecContext * cctx
Codec context of the camera's selected video stream.
float getCamVideoFPS() const override
void frameAvailable(std::shared_ptr< VideoFrame > frame)
Emitted when new frame available to use.
QString deviceName
Short name of the device for CameraDevice's open(QString)
This class is a wrapper to share a camera's captured video frames.
void openDevice()
Opens the video device and starts streaming.
VideoMode mode
What mode we tried to open the device in, all zeros means default mode.
AVCodecContext * cctxOrig
Codec context of the camera's selected video stream.
std::shared_ptr< VideoFrame > trackFrame()
Causes the VideoFrame class to maintain an internal reference for the frame.
void setupDevice(const QString &deviceName, const VideoMode &mode)
Change the device and mode.
int videoStreamIndex
A camera can have multiple streams, this is the one we're decoding.
CameraDevice * device
Non-owning pointer to an open CameraDevice, or nullptr. Not atomic, synced with memfences when become...
An ownernship and management class for AVFrames.
void stream()
Blocking. Decodes video stream and emits new frames.
AVFormatContext * context
Context of the open device, must always be valid.
QReadWriteLock deviceMutex
static void destroyInstance()
static Settings & getInstance()
Returns the singleton instance.
QFuture< void > streamFuture
Future of the streaming thread.
static CameraSource & getInstance()
Returns the singleton instance.
Describes a video mode supported by a device.
bool close()
Closes the device. Never fails.
float FPS
Frames per second supported by the device at this resolution.
void closeDevice()
Closes the video device and stops streaming.
QReadWriteLock streamMutex
void subscribe() override
If subscribe sucessfully opens the source, it will start emitting frameAvailable signals.
std::atomic_int subscriptions
Remember how many times we subscribed for RAII.
static void untrackFrames(const IDType &sourceID, bool releaseFrames=false)
Untracks all the frames for the given VideoSource, releasing them if specified.
static CameraDevice * open(QString devName, VideoMode mode=VideoMode())
Opens a device.
static bool isScreen(const QString &devName)
Checks if a device name specifies a display.
static QString getDefaultDeviceName()
Get the default device name.