Пример #1
0
void AVForm::updateVideoModes(int curIndex)
{
    if (curIndex<0 || curIndex>=videoDeviceList.size())
    {
        qWarning() << "Invalid index";
        return;
    }
    QString devName = videoDeviceList[curIndex].first;
    QVector<VideoMode> allVideoModes = CameraDevice::getVideoModes(devName);
    std::sort(allVideoModes.begin(), allVideoModes.end(),
        [](const VideoMode& a, const VideoMode& b)
            {return a.width!=b.width ? a.width>b.width :
                    a.height!=b.height ? a.height>b.height :
                    a.FPS>b.FPS;});
    bool previouslyBlocked = bodyUI->videoModescomboBox->blockSignals(true);
    bodyUI->videoModescomboBox->clear();

    // 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};
    std::map<int, int> bestModeInds;

    qDebug("available Modes:");
    for (int i=0; i<allVideoModes.size(); ++i)
    {
        VideoMode mode = allVideoModes[i];
        qDebug("width: %d, height: %d, FPS: %f, pixel format: %s", mode.width, mode.height, mode.FPS, CameraDevice::getPixelFormatString(mode.pixel_format).toStdString().c_str());

        // PS3-Cam protection, everything above 60fps makes no sense
        if(mode.FPS > 60)
            continue;

        for(auto iter = idealModes.begin(); iter != idealModes.end(); ++iter)
        {
            int res = iter->first;
            VideoMode idealMode = iter->second;
            // don't take approximately correct resolutions unless they really
            // are close
            if (mode.norm(idealMode) > 300)
                continue;

            if (bestModeInds.find(res) == bestModeInds.end())
            {
                bestModeInds[res] = i;
                continue;
            }
            int ind = bestModeInds[res];
            if (mode.norm(idealMode) < allVideoModes[ind].norm(idealMode))
            {
                bestModeInds[res] = i;
            }
            else if (mode.norm(idealMode) == allVideoModes[ind].norm(idealMode))
            {
                // prefer higher FPS and "better" pixel formats
                if (mode.FPS > allVideoModes[ind].FPS)
                {
                    bestModeInds[res] = i;
                }
                else if (mode.FPS == allVideoModes[ind].FPS &&
                        CameraDevice::betterPixelFormat(mode.pixel_format, allVideoModes[ind].pixel_format))
                {
                    bestModeInds[res] = i;
                }
            }
        }
    }
    qDebug("selected Modes:");
    int prefResIndex = -1;
    QSize prefRes = Settings::getInstance().getCamVideoRes();
    unsigned short prefFPS = Settings::getInstance().getCamVideoFPS();
    // Iterate backwards to show higest resolution first.
    videoModes.clear();
    for(auto iter = bestModeInds.rbegin(); iter != bestModeInds.rend(); ++iter)
    {
        int i = iter->second;
        VideoMode mode = allVideoModes[i];

        if (videoModes.contains(mode))
            continue;

        videoModes.append(mode);
        if (mode.width==prefRes.width() && mode.height==prefRes.height() && mode.FPS == prefFPS && prefResIndex==-1)
            prefResIndex = videoModes.size() - 1;
        QString str;
        qDebug("width: %d, height: %d, FPS: %f, pixel format: %s\n", mode.width, mode.height, mode.FPS, CameraDevice::getPixelFormatString(mode.pixel_format).toStdString().c_str());
        if (mode.height && mode.width)
            str += tr("%1p").arg(iter->first);
        else
            str += tr("Default resolution");
        bodyUI->videoModescomboBox->addItem(str);
    }
    if (videoModes.isEmpty())
        bodyUI->videoModescomboBox->addItem(tr("Default resolution"));
    bodyUI->videoModescomboBox->blockSignals(previouslyBlocked);
    if (prefResIndex != -1)
    {
        bodyUI->videoModescomboBox->setCurrentIndex(prefResIndex);
    }
    else
    {
        // If the user hasn't set a preffered resolution yet,
        // we'll pick the resolution in the middle of the list,
        // and the best FPS for that resolution.
        // If we picked the lowest resolution, the quality would be awful
        // but if we picked the largest, FPS would be bad and thus quality bad too.
        int numRes=0;
        QSize lastSize;
        for (int i=0; i<videoModes.size(); i++)
        {
            if (lastSize != QSize{videoModes[i].width, videoModes[i].height})
            {
                numRes++;
                lastSize = {videoModes[i].width, videoModes[i].height};
            }
        }
        int target = numRes/2;
        numRes=0;
        for (int i=0; i<videoModes.size(); i++)
        {
            if (lastSize != QSize{videoModes[i].width, videoModes[i].height})
            {
                numRes++;
                lastSize = {videoModes[i].width, videoModes[i].height};
            }
            if (numRes==target)
            {
                bodyUI->videoModescomboBox->setCurrentIndex(i);
                break;
            }
        }

        if (videoModes.size())
        {
            bodyUI->videoModescomboBox->setUpdatesEnabled(false);
            bodyUI->videoModescomboBox->setCurrentIndex(-1);
            bodyUI->videoModescomboBox->setUpdatesEnabled(true);
            bodyUI->videoModescomboBox->setCurrentIndex(0);
        }
        else
        {
            // We don't have any video modes, open it with the default mode
            camera.open(devName);
        }
    }
}
Пример #2
0
void AVForm::selectBestModes(QVector<VideoMode> &allVideoModes)
{
    // Identify the best resolutions available for the supposed XXXXp resolutions.
    std::map<int, VideoMode> idealModes;
    idealModes[120] = VideoMode(160, 120);
    idealModes[240] = VideoMode(430, 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)
    {
        VideoMode mode = allVideoModes[i];

        // PS3-Cam protection, everything above 60fps makes no sense
        if (mode.FPS > 60)
            continue;

        for (auto iter = idealModes.begin(); iter != idealModes.end(); ++iter)
        {
            int res = iter->first;
            VideoMode idealMode = iter->second;
            // don't take approximately correct resolutions unless they really
            // are close
            if (mode.norm(idealMode) > 300)
                continue;

            if (bestModeInds.find(res) == bestModeInds.end())
            {
                bestModeInds[res] = i;
                continue;
            }

            int index = bestModeInds[res];
            VideoMode best = allVideoModes[index];
            if (mode.norm(idealMode) < best.norm(idealMode))
            {
                bestModeInds[res] = i;
                continue;
            }

            if (mode.norm(idealMode) == best.norm(idealMode))
            {
                // prefer higher FPS and "better" pixel formats
                if (mode.FPS > best.FPS)
                {
                    bestModeInds[res] = i;
                    continue;
                }

                bool better = CameraDevice::betterPixelFormat(mode.pixel_format, best.pixel_format);
                if (mode.FPS >= best.FPS && better)
                    bestModeInds[res] = i;
            }
        }
    }

    QVector<VideoMode> newVideoModes;
    for (auto it = bestModeInds.rbegin(); it != bestModeInds.rend(); ++it)
    {
        VideoMode mode = allVideoModes[it->second];

        if (newVideoModes.empty())
        {
            newVideoModes.push_back(mode);
        }
        else
        {
            int size = getModeSize(mode);
            auto result = std::find_if(newVideoModes.cbegin(), newVideoModes.cend(),
                                       [size](VideoMode mode) { return getModeSize(mode) == size; });

            if (result == newVideoModes.end())
                newVideoModes.push_back(mode);
        }
    }
    allVideoModes = newVideoModes;
}