mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
feat(cameradevice, avform): Added ability of screen selection
This commit is contained in:
parent
fd701df101
commit
d781a4f762
|
@ -103,12 +103,6 @@ out:
|
|||
return dev;
|
||||
}
|
||||
|
||||
CameraDevice* CameraDevice::open(QString devName)
|
||||
{
|
||||
VideoMode mode = VideoMode();
|
||||
return open(devName, mode);
|
||||
}
|
||||
|
||||
CameraDevice* CameraDevice::open(QString devName, VideoMode mode)
|
||||
{
|
||||
if (!getDefaultInputFormat())
|
||||
|
@ -149,26 +143,14 @@ CameraDevice* CameraDevice::open(QString devName, VideoMode mode)
|
|||
screen.setHeight((screen.height() * pixRatio)-2);
|
||||
}
|
||||
av_dict_set(&options, "video_size", QString("%1x%2").arg(screen.width()).arg(screen.height()).toStdString().c_str(), 0);
|
||||
devName += QString("+%1,%2").arg(QString().setNum(mode.x), QString().setNum(mode.y));
|
||||
|
||||
int FPS = 5;
|
||||
if (mode.FPS)
|
||||
av_dict_set(&options, "framerate", QString().setNum(mode.FPS).toStdString().c_str(), 0);
|
||||
else
|
||||
av_dict_set(&options, "framerate", QString().setNum(5).toStdString().c_str(), 0);
|
||||
FPS = mode.FPS;
|
||||
|
||||
av_dict_set(&options, "framerate", QString().setNum(FPS).toStdString().c_str(), 0);
|
||||
}
|
||||
#endif
|
||||
#ifdef Q_OS_WIN
|
||||
else if (devName.startsWith("gdigrab#"))
|
||||
{
|
||||
av_dict_set(&options, "framerate", QString().setNum(5).toStdString().c_str(), 0);
|
||||
}
|
||||
#endif
|
||||
#ifdef Q_OS_WIN
|
||||
else if (iformat->name == QString("dshow") && mode)
|
||||
{
|
||||
av_dict_set(&options, "video_size", QString("%1x%2").arg(mode.width).arg(mode.height).toStdString().c_str(), 0);
|
||||
av_dict_set(&options, "framerate", QString().setNum(mode.FPS).toStdString().c_str(), 0);
|
||||
}
|
||||
#endif
|
||||
#ifdef Q_OS_LINUX
|
||||
else if (iformat->name == QString("video4linux2,v4l2") && mode)
|
||||
{
|
||||
av_dict_set(&options, "video_size", QString("%1x%2").arg(mode.width).arg(mode.height).toStdString().c_str(), 0);
|
||||
|
@ -180,6 +162,20 @@ CameraDevice* CameraDevice::open(QString devName, VideoMode mode)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef Q_OS_WIN
|
||||
else if (devName.startsWith("gdigrab#"))
|
||||
{
|
||||
av_dict_set(&options, "framerate", QString().setNum(5).toStdString().c_str(), 0);
|
||||
av_dict_set(&options, "offset_x", QString().setNum(mode.x).toStdString().c_str(), 0);
|
||||
av_dict_set(&options, "offset_y", QString().setNum(mode.y).toStdString().c_str(), 0);
|
||||
av_dict_set(&options, "video_size", QString("%1x%2").arg(mode.width).arg(mode.height).toStdString().c_str(), 0);
|
||||
}
|
||||
else if (iformat->name == QString("dshow") && mode)
|
||||
{
|
||||
av_dict_set(&options, "video_size", QString("%1x%2").arg(mode.width).arg(mode.height).toStdString().c_str(), 0);
|
||||
av_dict_set(&options, "framerate", QString().setNum(mode.FPS).toStdString().c_str(), 0);
|
||||
}
|
||||
#endif
|
||||
#ifdef Q_OS_OSX
|
||||
else if (iformat->name == QString("avfoundation"))
|
||||
{
|
||||
|
@ -215,19 +211,15 @@ void CameraDevice::open()
|
|||
|
||||
bool CameraDevice::close()
|
||||
{
|
||||
if (--refcount <= 0)
|
||||
{
|
||||
openDeviceLock.lock();
|
||||
openDevices.remove(devName);
|
||||
openDeviceLock.unlock();
|
||||
avformat_close_input(&context);
|
||||
delete this;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (--refcount > 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
openDeviceLock.lock();
|
||||
openDevices.remove(devName);
|
||||
openDeviceLock.unlock();
|
||||
avformat_close_input(&context);
|
||||
delete this;
|
||||
return true;
|
||||
}
|
||||
|
||||
QVector<QPair<QString, QString>> CameraDevice::getRawDeviceListGeneric()
|
||||
|
@ -351,9 +343,33 @@ QString CameraDevice::getDefaultDeviceName()
|
|||
return devlist[0].first;
|
||||
}
|
||||
|
||||
bool CameraDevice::isScreen(const QString &devName)
|
||||
{
|
||||
return devName.startsWith("x11grab") || devName.startsWith("gdigrab");
|
||||
}
|
||||
|
||||
QVector<VideoMode> CameraDevice::getScreenModes()
|
||||
{
|
||||
QList<QScreen*> screens = QApplication::screens();
|
||||
QVector<VideoMode> result;
|
||||
|
||||
std::for_each(screens.begin(), screens.end(), [&result](QScreen *s)
|
||||
{
|
||||
QRect rect = s->geometry();
|
||||
QPoint p = rect.topLeft();
|
||||
|
||||
VideoMode mode(rect.width(), rect.height(), p.x(), p.y());
|
||||
result.push_back(mode);
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QVector<VideoMode> CameraDevice::getVideoModes(QString devName)
|
||||
{
|
||||
if (!iformat);
|
||||
else if (isScreen(devName))
|
||||
return getScreenModes();
|
||||
#ifdef Q_OS_WIN
|
||||
else if (iformat->name == QString("dshow"))
|
||||
return DirectShow::getDeviceModes(devName);
|
||||
|
@ -417,6 +433,7 @@ bool CameraDevice::getDefaultInputFormat()
|
|||
if ((iformat = av_find_input_format("dshow")))
|
||||
return true;
|
||||
if ((iformat = av_find_input_format("vfwcap")))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_OSX
|
||||
|
|
|
@ -41,15 +41,12 @@ struct AVDictionary;
|
|||
class CameraDevice
|
||||
{
|
||||
public:
|
||||
/// Opens a device, creating a new one if needed
|
||||
/// Returns a nullptr if the device couldn't be opened
|
||||
static CameraDevice* open(QString devName);
|
||||
/// Opens a device, creating a new one if needed
|
||||
/// If the device is alreay open in another mode, the mode
|
||||
/// will be ignored and the existing device is used
|
||||
/// If the mode does not exist, a new device can't be opened
|
||||
/// Returns a nullptr if the device couldn't be opened
|
||||
static CameraDevice* open(QString devName, VideoMode mode);
|
||||
static CameraDevice* open(QString devName, VideoMode mode = VideoMode());
|
||||
void open(); ///< Opens the device again. Never fails
|
||||
bool close(); ///< Closes the device. Never fails. If returns true, "this" becomes invalid
|
||||
|
||||
|
@ -69,11 +66,15 @@ public:
|
|||
/// or the system default.
|
||||
static QString getDefaultDeviceName();
|
||||
|
||||
/// Checks if a device name specifies a display
|
||||
static bool isScreen(const QString &devName);
|
||||
|
||||
private:
|
||||
CameraDevice(const QString &devName, AVFormatContext *context);
|
||||
static CameraDevice* open(QString devName, AVDictionary** options);
|
||||
static bool getDefaultInputFormat(); ///< Sets CameraDevice::iformat, returns success/failure
|
||||
static QVector<QPair<QString, QString> > getRawDeviceListGeneric(); ///< Uses avdevice_list_devices
|
||||
static QVector<VideoMode> getScreenModes(); ///< Returns avaliable screen modes with offset
|
||||
|
||||
public:
|
||||
const QString devName; ///< Short name of the device
|
||||
|
|
|
@ -136,13 +136,13 @@ void AVForm::showEvent(QShowEvent* event)
|
|||
|
||||
void AVForm::onVideoModesIndexChanged(int index)
|
||||
{
|
||||
if (index<0 || index>=videoModes.size())
|
||||
if (index < 0 || index >= videoModes.size())
|
||||
{
|
||||
qWarning() << "Invalid mode index";
|
||||
return;
|
||||
}
|
||||
int devIndex = bodyUI->videoDevCombobox->currentIndex();
|
||||
if (devIndex<0 || devIndex>=videoModes.size())
|
||||
if (devIndex < 0 || devIndex >= videoDeviceList.size())
|
||||
{
|
||||
qWarning() << "Invalid device index";
|
||||
return;
|
||||
|
@ -150,8 +150,7 @@ void AVForm::onVideoModesIndexChanged(int index)
|
|||
QString devName = videoDeviceList[devIndex].first;
|
||||
VideoMode mode = videoModes[index];
|
||||
|
||||
QRect rect(mode.x, mode.y, mode.width, mode.height);
|
||||
Settings::getInstance().setCamVideoRes(rect);
|
||||
Settings::getInstance().setCamVideoRes(mode.toRect());
|
||||
Settings::getInstance().setCamVideoFPS(mode.FPS);
|
||||
camera.open(devName, mode);
|
||||
}
|
||||
|
@ -228,7 +227,7 @@ void AVForm::selectBestModes(QVector<VideoMode> &allVideoModes)
|
|||
allVideoModes = newVideoModes;
|
||||
}
|
||||
|
||||
void AVForm::fillModesComboBox()
|
||||
void AVForm::fillCameraModesComboBox()
|
||||
{
|
||||
bool previouslyBlocked = bodyUI->videoModescomboBox->blockSignals(true);
|
||||
bodyUI->videoModescomboBox->clear();
|
||||
|
@ -272,6 +271,25 @@ int AVForm::searchPreferredIndex()
|
|||
return -1;
|
||||
}
|
||||
|
||||
void AVForm::fillScreenModesComboBox()
|
||||
{
|
||||
bool previouslyBlocked = bodyUI->videoModescomboBox->blockSignals(true);
|
||||
bodyUI->videoModescomboBox->clear();
|
||||
|
||||
for(int i = 0; i < videoModes.size(); i++)
|
||||
{
|
||||
VideoMode mode = videoModes[i];
|
||||
QString pixelFormat = CameraDevice::getPixelFormatString(mode.pixel_format);
|
||||
qDebug("%dx%d+%d,%d FPS: %f, pixel format: %s\n", mode.width, mode.height, mode.x, mode.y, mode.FPS, pixelFormat.toStdString().c_str());
|
||||
|
||||
QString name = QString("Screen %1").arg(i + 1);
|
||||
bodyUI->videoModescomboBox->addItem(name);
|
||||
}
|
||||
|
||||
bodyUI->videoModescomboBox->addItem(tr("Select region"));
|
||||
bodyUI->videoModescomboBox->blockSignals(previouslyBlocked);
|
||||
}
|
||||
|
||||
void AVForm::updateVideoModes(int curIndex)
|
||||
{
|
||||
if (curIndex < 0 || curIndex >= videoDeviceList.size())
|
||||
|
@ -283,11 +301,19 @@ void AVForm::updateVideoModes(int curIndex)
|
|||
QVector<VideoMode> allVideoModes = CameraDevice::getVideoModes(devName);
|
||||
|
||||
qDebug("available Modes:");
|
||||
selectBestModes(allVideoModes);
|
||||
videoModes = allVideoModes;
|
||||
if (CameraDevice::isScreen(devName))
|
||||
{
|
||||
videoModes = allVideoModes;
|
||||
fillScreenModesComboBox();
|
||||
}
|
||||
else
|
||||
{
|
||||
selectBestModes(allVideoModes);
|
||||
videoModes = allVideoModes;
|
||||
|
||||
qDebug("selected Modes:");
|
||||
fillModesComboBox();
|
||||
qDebug("selected Modes:");
|
||||
fillCameraModesComboBox();
|
||||
}
|
||||
|
||||
int preferedIndex = searchPreferredIndex();
|
||||
if (preferedIndex!= -1)
|
||||
|
@ -307,7 +333,7 @@ void AVForm::updateVideoModes(int curIndex)
|
|||
|
||||
void AVForm::onVideoDevChanged(int index)
|
||||
{
|
||||
if (index<0 || index>=videoDeviceList.size())
|
||||
if (index < 0 || index >= videoDeviceList.size())
|
||||
{
|
||||
qWarning() << "Invalid index";
|
||||
return;
|
||||
|
|
|
@ -47,7 +47,8 @@ private:
|
|||
void getVideoDevices();
|
||||
|
||||
void selectBestModes(QVector<VideoMode> &allVideoModes);
|
||||
void fillModesComboBox();
|
||||
void fillCameraModesComboBox();
|
||||
void fillScreenModesComboBox();
|
||||
int searchPreferredIndex();
|
||||
|
||||
void createVideoSurface();
|
||||
|
|
Loading…
Reference in New Issue
Block a user