1
0
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:
Diadlo 2016-06-15 02:04:39 +03:00
parent fd701df101
commit d781a4f762
No known key found for this signature in database
GPG Key ID: 5AF9F2E29107C727
4 changed files with 96 additions and 51 deletions

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -47,7 +47,8 @@ private:
void getVideoDevices();
void selectBestModes(QVector<VideoMode> &allVideoModes);
void fillModesComboBox();
void fillCameraModesComboBox();
void fillScreenModesComboBox();
int searchPreferredIndex();
void createVideoSurface();