mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
feat(videomode): Added possible video shift
This commit is contained in:
parent
2d861ee25b
commit
fd701df101
|
@ -242,7 +242,7 @@ void Settings::loadGlobal()
|
|||
|
||||
s.beginGroup("Video");
|
||||
videoDev = s.value("videoDev", "").toString();
|
||||
camVideoRes = s.value("camVideoRes",QSize()).toSize();
|
||||
camVideoRes = s.value("camVideoRes", QRect()).toRect();
|
||||
camVideoFPS = s.value("camVideoFPS", 0).toUInt();
|
||||
s.endGroup();
|
||||
|
||||
|
@ -1412,13 +1412,13 @@ void Settings::setOutVolume(int volume)
|
|||
outVolume = volume;
|
||||
}
|
||||
|
||||
QSize Settings::getCamVideoRes() const
|
||||
QRect Settings::getCamVideoRes() const
|
||||
{
|
||||
QMutexLocker locker{&bigLock};
|
||||
return camVideoRes;
|
||||
}
|
||||
|
||||
void Settings::setCamVideoRes(QSize newValue)
|
||||
void Settings::setCamVideoRes(QRect newValue)
|
||||
{
|
||||
QMutexLocker locker{&bigLock};
|
||||
camVideoRes = newValue;
|
||||
|
|
|
@ -190,8 +190,8 @@ public:
|
|||
QString getVideoDev() const;
|
||||
void setVideoDev(const QString& deviceSpecifier);
|
||||
|
||||
QSize getCamVideoRes() const;
|
||||
void setCamVideoRes(QSize newValue);
|
||||
QRect getCamVideoRes() const;
|
||||
void setCamVideoRes(QRect newValue);
|
||||
|
||||
unsigned short getCamVideoFPS() const;
|
||||
void setCamVideoFPS(unsigned short newValue);
|
||||
|
@ -434,7 +434,7 @@ private:
|
|||
|
||||
// Video
|
||||
QString videoDev;
|
||||
QSize camVideoRes;
|
||||
QRect camVideoRes;
|
||||
unsigned short camVideoFPS;
|
||||
|
||||
struct friendProp
|
||||
|
|
|
@ -73,7 +73,7 @@ CameraDevice* CameraDevice::open(QString devName, AVDictionary** options)
|
|||
format = iformat;
|
||||
}
|
||||
|
||||
if (avformat_open_input(&fctx, devName.toStdString().c_str(), format, options)<0)
|
||||
if (avformat_open_input(&fctx, devName.toStdString().c_str(), format, options) < 0)
|
||||
goto out;
|
||||
|
||||
// Fix avformat_find_stream_info hanging on garbage input
|
||||
|
@ -105,7 +105,7 @@ out:
|
|||
|
||||
CameraDevice* CameraDevice::open(QString devName)
|
||||
{
|
||||
VideoMode mode{0,0,0,0};
|
||||
VideoMode mode = VideoMode();
|
||||
return open(devName, mode);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ extern "C" {
|
|||
CameraSource* CameraSource::instance{nullptr};
|
||||
|
||||
CameraSource::CameraSource()
|
||||
: deviceName{"none"}, device{nullptr}, mode(VideoMode{0,0,0,0}),
|
||||
: deviceName{"none"}, device{nullptr}, mode(VideoMode()),
|
||||
cctx{nullptr}, cctxOrig{nullptr}, videoStreamIndex{-1},
|
||||
_isOpen{false}, streamBlocker{false}, subscriptions{0}
|
||||
{
|
||||
|
@ -67,7 +67,7 @@ void CameraSource::open()
|
|||
|
||||
void CameraSource::open(const QString& deviceName)
|
||||
{
|
||||
open(deviceName, VideoMode{0,0,0,0});
|
||||
open(deviceName, VideoMode());
|
||||
}
|
||||
|
||||
void CameraSource::open(const QString& DeviceName, VideoMode Mode)
|
||||
|
@ -206,7 +206,7 @@ void CameraSource::unsubscribe()
|
|||
|
||||
bool CameraSource::openDevice()
|
||||
{
|
||||
qDebug() << "Opening device "<<deviceName;
|
||||
qDebug() << "Opening device " << deviceName;
|
||||
|
||||
if (device)
|
||||
{
|
||||
|
@ -216,10 +216,8 @@ bool CameraSource::openDevice()
|
|||
|
||||
// We need to create a new CameraDevice
|
||||
AVCodec* codec;
|
||||
if (mode)
|
||||
device = CameraDevice::open(deviceName, mode);
|
||||
else
|
||||
device = CameraDevice::open(deviceName);
|
||||
device = CameraDevice::open(deviceName, mode);
|
||||
|
||||
if (!device)
|
||||
{
|
||||
qWarning() << "Failed to open device!";
|
||||
|
@ -240,25 +238,36 @@ bool CameraSource::openDevice()
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (videoStreamIndex == -1)
|
||||
{
|
||||
qWarning() << "Video stream not found";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get a pointer to the codec context for the video stream
|
||||
cctxOrig = device->context->streams[videoStreamIndex]->codec;
|
||||
codec = avcodec_find_decoder(cctxOrig->codec_id);
|
||||
if(!codec)
|
||||
{
|
||||
qWarning() << "Codec not found";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Copy context, since we apparently aren't allowed to use the original
|
||||
cctx = avcodec_alloc_context3(codec);
|
||||
if(avcodec_copy_context(cctx, cctxOrig) != 0)
|
||||
{
|
||||
qWarning() << "Can't copy context";
|
||||
return false;
|
||||
}
|
||||
|
||||
cctx->refcounted_frames = 1;
|
||||
|
||||
// Open codec
|
||||
if(avcodec_open2(cctx, codec, nullptr)<0)
|
||||
{
|
||||
qWarning() << "Can't open codec";
|
||||
avcodec_free_context(&cctx);
|
||||
return false;
|
||||
}
|
||||
|
@ -288,6 +297,7 @@ void CameraSource::closeDevice()
|
|||
std::shared_ptr<VideoFrame> vframe = freelist[i].lock();
|
||||
if (!vframe)
|
||||
continue;
|
||||
|
||||
vframe->releaseFrame();
|
||||
}
|
||||
freelist.clear();
|
||||
|
@ -311,14 +321,15 @@ void CameraSource::stream()
|
|||
AVFrame* frame = av_frame_alloc();
|
||||
if (!frame)
|
||||
return;
|
||||
|
||||
frame->opaque = nullptr;
|
||||
|
||||
AVPacket packet;
|
||||
if (av_read_frame(device->context, &packet)<0)
|
||||
if (av_read_frame(device->context, &packet) < 0)
|
||||
return;
|
||||
|
||||
// Only keep packets from the right stream;
|
||||
if (packet.stream_index==videoStreamIndex)
|
||||
if (packet.stream_index == videoStreamIndex)
|
||||
{
|
||||
// Decode video frame
|
||||
int frameFinished;
|
||||
|
@ -340,7 +351,8 @@ void CameraSource::stream()
|
|||
av_packet_unref(&packet);
|
||||
};
|
||||
|
||||
forever {
|
||||
forever
|
||||
{
|
||||
biglock.lock();
|
||||
|
||||
// When a thread makes device null, it releases it, so we acquire here
|
||||
|
@ -357,6 +369,7 @@ void CameraSource::stream()
|
|||
biglock.unlock();
|
||||
while (streamBlocker)
|
||||
QThread::yieldCurrentThread();
|
||||
|
||||
QThread::yieldCurrentThread();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,12 +84,8 @@ NetCamView::NetCamView(int friendId, QWidget* parent)
|
|||
videoSurface->setAvatar(pixmap);
|
||||
});
|
||||
|
||||
VideoMode videoMode;
|
||||
QSize videoSize = Settings::getInstance().getCamVideoRes();
|
||||
videoMode.width = videoSize.width();
|
||||
videoMode.height = videoSize.height();
|
||||
QRect videoSize = Settings::getInstance().getCamVideoRes();
|
||||
qDebug() << "SIZER" << videoSize;
|
||||
videoMode.FPS = Settings::getInstance().getCamVideoFPS();
|
||||
}
|
||||
|
||||
NetCamView::~NetCamView()
|
||||
|
|
|
@ -21,13 +21,36 @@
|
|||
#ifndef VIDEOMODE_H
|
||||
#define VIDEOMODE_H
|
||||
|
||||
#include <QRect>
|
||||
#include <cstdint>
|
||||
|
||||
/// Describes a video mode supported by a device
|
||||
struct VideoMode
|
||||
{
|
||||
unsigned short width, height; ///< Displayed video resolution (NOT frame resolution)
|
||||
unsigned short x, y; ///< Coordinates of upper-left corner
|
||||
float FPS; ///< Max frames per second supported by the device at this resolution
|
||||
uint32_t pixel_format;
|
||||
|
||||
VideoMode(int width = 0, int height = 0, int x = 0, int y = 0,
|
||||
int FPS = 0, int format = 0) :
|
||||
width(width), height(height), x(x), y(y),
|
||||
FPS(FPS), pixel_format(format)
|
||||
{
|
||||
}
|
||||
|
||||
VideoMode(QRect rect) :
|
||||
width(rect.width()), height(rect.height()),
|
||||
x(rect.x()), y(rect.y()),
|
||||
FPS(0), pixel_format(0)
|
||||
{
|
||||
}
|
||||
|
||||
QRect toRect() const
|
||||
{
|
||||
return QRect(x, y, width, height);
|
||||
}
|
||||
|
||||
/// All zeros means a default/unspecified mode
|
||||
operator bool() const
|
||||
{
|
||||
|
@ -38,6 +61,8 @@ struct VideoMode
|
|||
{
|
||||
return width == other.width
|
||||
&& height == other.height
|
||||
&& x == other.x
|
||||
&& y == other.y
|
||||
&& FPS == other.FPS
|
||||
&& pixel_format == other.pixel_format;
|
||||
}
|
||||
|
|
|
@ -149,7 +149,9 @@ void AVForm::onVideoModesIndexChanged(int index)
|
|||
}
|
||||
QString devName = videoDeviceList[devIndex].first;
|
||||
VideoMode mode = videoModes[index];
|
||||
Settings::getInstance().setCamVideoRes(QSize(mode.width, mode.height));
|
||||
|
||||
QRect rect(mode.x, mode.y, mode.width, mode.height);
|
||||
Settings::getInstance().setCamVideoRes(rect);
|
||||
Settings::getInstance().setCamVideoFPS(mode.FPS);
|
||||
camera.open(devName, mode);
|
||||
}
|
||||
|
@ -158,12 +160,12 @@ void AVForm::selectBestModes(QVector<VideoMode> &allVideoModes)
|
|||
{
|
||||
// Identify the best resolutions available for the supposed XXXXp resolutions.
|
||||
std::map<int, VideoMode> idealModes;
|
||||
idealModes[120] = {160,120,0,0};
|
||||
idealModes[240] = {460,240,0,0};
|
||||
idealModes[360] = {640,360,0,0};
|
||||
idealModes[480] = {854,480,0,0};
|
||||
idealModes[720] = {1280,720,0,0};
|
||||
idealModes[1080] = {1920,1080,0,0};
|
||||
idealModes[120] = VideoMode(160, 120);
|
||||
idealModes[240] = VideoMode(460, 240);
|
||||
idealModes[360] = VideoMode(640, 360);
|
||||
idealModes[480] = VideoMode(854, 480);
|
||||
idealModes[720] = VideoMode(1280, 720);
|
||||
idealModes[1080] = VideoMode(1920, 1080);
|
||||
|
||||
std::map<int, int> bestModeInds;
|
||||
for (int i = 0; i < allVideoModes.size(); ++i)
|
||||
|
@ -255,7 +257,7 @@ void AVForm::fillModesComboBox()
|
|||
|
||||
int AVForm::searchPreferredIndex()
|
||||
{
|
||||
QSize prefRes = Settings::getInstance().getCamVideoRes();
|
||||
QRect prefRes = Settings::getInstance().getCamVideoRes();
|
||||
unsigned short prefFPS = Settings::getInstance().getCamVideoFPS();
|
||||
|
||||
for (int i = 0; i < videoModes.size(); i++)
|
||||
|
|
Loading…
Reference in New Issue
Block a user