<commit_before>#include "game.h"
#include <QGLWidget>
#include <QChar>

Game::Game(ReadyPage *parent_readypage, MainWindow *parent_mainwindow,
           QString mapPath, int gametype):
    QObject(parent_readypage)
{
    readypage = parent_readypage;
    mainwindow  = parent_mainwindow;

    scene = new QGraphicsScene(mainwindow);
    view = new QGraphicsView(scene, mainwindow);
    view->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
    mainwindow->addviewWidget(view);
    initSceneBackground();

    loadTexture();

    if(gametype == SinglePlayer) {
        map = new Map(NULL, mapPath);
        if(!map->loadMap()) {
            readypage->back();
            delete this;
        }
        initBlock();
        initPlayer();
    } else {
        connectServer();
        connect(&tcpSocket,SIGNAL(connected()),this,SLOT(firstDataSubmit()));
        connect(&tcpSocket,SIGNAL(readyRead()),this,SLOT(getFirst()));
    }
}

Game::~Game()
{
    delete map;
}

//bool Game::genHeadPic(QImage image, Camp camp, QString playerName)
//{
//}

void Game::initSceneBackground()
{
    //	scene->setForegroundBrush(QColor(200, 255, 255));
    scene->setBackgroundBrush(QPixmap(":/image/pix3.png"));
    //	scene->setSceneRect(-100, -100, 200, 200);
}

void Game::getHeadPic()
{
    QSettings settings("Funcatching Project", "Funcatching");
    settings.beginGroup("HeadImage");
    QString path = settings.value("head_image", "").toString();
    QFile a(path);
    if(!a.exists())
    {
        return;
    }
    settings.endGroup();
    headImage =  new QImage;
    headImage->load(path);
}

void Game::connectServer()
{
    QSettings settings("Funcatching Project", "Funcatching");
    settings.beginGroup("IP Address");
    QHostAddress *address = new QHostAddress(settings.value("IP").toString());
    tcpSocket.connectToHost(*address,2048);
    settings.endGroup();
}

void Game::initBlock()
{
    int rowsize = map->mapRowSize(0);
    int columnsize = map->mapRowSize(0);
    QPixmap tex(":/tex/3.png");
    for(int i = 0; i < rowsize; i++) {
        for (int j = 0; j < columnsize; j++) {
            QGraphicsPixmapItem *block = new QGraphicsPixmapItem(tex);
            block->setPos(32 * j, 32 * i);
            scene->addItem(block);
        }
    }
}

void Game::initPlayer()
{

}

void Game::loadTexture()
{
	QDir dir(":/tex/");
	QString tmp_str;
	QStringList list, filter;

	filter << "*.png";
	dir.setNameFilters(filter);
	list = dir.entryList();
	qDebug() << list;
	//对材质列表按名称排序
	{
		int a = 0, b = 0, length = list.size(), m = length;
		for (int i = 1; i < length; ++i) {
			m -= 1;
//			tmp_str = QString(list[i][0]);
////			for (int x = 1; x < list[i].size(); ++x) {
//				if (list[i][1].toAscii() == '1' || list[i][1].toAscii() == '2' || list[i][1].toAscii() == '3' || list[i][1].toAscii() == '4' || list[i][1].toAscii() == '5' || list[i][1].toAscii() == '6' || list[i][1].toAscii() == '7' || list[i][1].toAscii() == '8' || list[i][1].toAscii() == '9' || list[i][1].toAscii() == '0')
//				        tmp_str.append(list[i][1]);
////			}
//			a = tmp_str.toInt();
			for (int j = 0; j < m; ++j) {
				tmp_str = QString(list[j][0]);
	//			for (int x = 1; x < list[i].size(); ++x) {
					if (list[j][1].toAscii() == '1' || list[j][1].toAscii() == '2' || list[j][1].toAscii() == '3' || list[j][1].toAscii() == '4' || list[j][1].toAscii() == '5' || list[j][1].toAscii() == '6' || list[j][1].toAscii() == '7' || list[j][1].toAscii() == '8' || list[j][1].toAscii() == '9' || list[j][1].toAscii() == '0')
						tmp_str.append(list[j][1]);
	//			}
				a = tmp_str.toInt();

                                tmp_str = QString(list[j + 1][0]);
//                                for (int x = 1; x < list[j].size(); ++x) {
					if (list[j + 1][1].toAscii() == '1' || list[j + 1][1].toAscii() == '2' || list[j + 1][1].toAscii() == '3' || list[j + 1][1].toAscii() == '4' || list[j + 1][1].toAscii() == '5' || list[j + 1][1].toAscii() == '6' || list[j + 1][1].toAscii() == '7' || list[j + 1][1].toAscii() == '8' || list[j + 1][1].toAscii() == '9' || list[j + 1][1].toAscii() == '0')
						tmp_str.append(list[j + 1][1]);
//                                }
				b = tmp_str.toInt();
				if (a > b) {
					tmp_str = list[j];
					list[j] = list[j + 1];
					list[j + 1] = tmp_str;
				}
			}
		}
		qDebug() << list;
//		for (int i = 0; i < list.size() - 1; ++i) {
//			tmp_str = QString(list[i][0]);
//			if (i >= 10)
//				tmp_str.append(list[i][1]);
//			a = tmp_str.toInt();
//			for (int j = i + 1; j < list.size(); ++j) {
//				tmp_str = QString(list[j][0]);
//				if (j >= 10)
//					tmp_str.append(list[j][1]);
//				b = tmp_str.toInt();

//				if (a > b) {
//					tmp_str = list[i];
//					list[i] = list[j];
//					list[j] = tmp_str;
//				}
//			}
//		}
	}
	//载入材质
//	int i = 0, previous = 0;
//	{
//		QList<QPixmap> newlist;
//		texture.append(newlist);
//	}
//	foreach (QString texname, list) {

//		tmp_str = QString(texname[0]);
//		i = tmp_str.toInt();
//		if (previous != i) {
//			QList<QPixmap> newlist;
//			texture.append(newlist);
//			previous = i;
//		}
//		texture[previous].append(QPixmap(dir.absoluteFilePath(texname)));
//	}
}

void Game::firstDataSubmit()
{
    qDebug()<<"hehe";
    QByteArray block;
    QDataStream out(&block,QIODevice::WriteOnly);

    QSettings settings("Funcatching Project", "Funcatching");
    settings.beginGroup("Player Name");
    player_name = settings.value("name").toString();
    settings.endGroup();

    out.setVersion(QDataStream::Qt_4_8);
    out<<quint32(0)<<player_name;//<<headImage;
    out.device()->seek(0);
    out<<quint32(block.size()-sizeof(quint16));
    tcpSocket.write(block);

    disconnect(&tcpSocket,SIGNAL(connected()),this,SLOT(firstDataSubmit()));
}

void initHeadPic()
{

}

void Game::getFirst()
{
    QDataStream in(&tcpSocket);
    in.setVersion(QDataStream::Qt_4_8);

    while(nextBlockSize==0){
        in >> nextBlockSize;
        if(nextBlockSize<tcpSocket.bytesAvailable())
            break;
    }
    unsigned short player_index;
    bool identity;
    unsigned short x,y,z;
    QString player_name;
    QImage *player_image = new QImage;

    in >> player_index;
    for(int i=0;i<=player_index;i++){
        in >>/* player_image >>*/ player_name >>identity >> x >> y >> z;
        storing_player *newPlayer;
        newPlayer->identety = identity;
        newPlayer->x = x;
        newPlayer->y = y;
        newPlayer->z = z;
        player.insert(i,newPlayer);
//        player_headImages->append(player_image);
    }
}
<commit_msg>asdfasf<commit_after>#include "game.h"
#include <QGLWidget>
#include <QChar>

Game::Game(ReadyPage *parent_readypage, MainWindow *parent_mainwindow,
           QString mapPath, int gametype):
    QObject(parent_readypage)
{
    readypage = parent_readypage;
    mainwindow  = parent_mainwindow;

    scene = new QGraphicsScene(mainwindow);
    view = new QGraphicsView(scene, mainwindow);
    view->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
    mainwindow->addviewWidget(view);
    initSceneBackground();

    loadTexture();

    if(gametype == SinglePlayer) {
        map = new Map(NULL, mapPath);
        if(!map->loadMap()) {
            readypage->back();
            delete this;
        }
        initBlock();
        initPlayer();
    } else {
        connectServer();
        connect(&tcpSocket,SIGNAL(connected()),this,SLOT(firstDataSubmit()));
        connect(&tcpSocket,SIGNAL(readyRead()),this,SLOT(getFirst()));
    }
}

Game::~Game()
{
    delete map;
}

//bool Game::genHeadPic(QImage image, Camp camp, QString playerName)
//{
//}

void Game::initSceneBackground()
{
    //	scene->setForegroundBrush(QColor(200, 255, 255));
    scene->setBackgroundBrush(QPixmap(":/image/pix3.png"));
    //	scene->setSceneRect(-100, -100, 200, 200);
}

void Game::getHeadPic()
{
    QSettings settings("Funcatching Project", "Funcatching");
    settings.beginGroup("HeadImage");
    QString path = settings.value("head_image", "").toString();
    QFile a(path);
    if(!a.exists())
    {
        return;
    }
    settings.endGroup();
    headImage =  new QImage;
    headImage->load(path);
}

void Game::connectServer()
{
    QSettings settings("Funcatching Project", "Funcatching");
    settings.beginGroup("IP Address");
    QHostAddress *address = new QHostAddress(settings.value("IP").toString());
    tcpSocket.connectToHost(*address,2048);
    settings.endGroup();
}

void Game::initBlock()
{
    int rowsize = map->mapRowSize(0);
    int columnsize = map->mapRowSize(0);
    QPixmap tex(":/tex/3.png");
    for(int i = 0; i < rowsize; i++) {
        for (int j = 0; j < columnsize; j++) {
            QGraphicsPixmapItem *block = new QGraphicsPixmapItem(tex);
            block->setPos(32 * j, 32 * i);
            scene->addItem(block);
        }
    }
}

void Game::initPlayer()
{

}

void Game::loadTexture()
{
	QDir dir(":/tex/");
	QString tmp_str;
	QStringList list, filter;

	filter << "*.png";
	dir.setNameFilters(filter);
	list = dir.entryList();
	qDebug() << list;

	//对材质列表按名称排序
	{
		int a = 0, b = 0, length = list.size(), m = length;
		for (int i = 1; i < length; ++i) {
			m -= 1;
			for (int j = 0; j < m; ++j) {
				tmp_str = QString(list[j][0]);
					if (list[j][1].toAscii() == '1' || list[j][1].toAscii() == '2' || list[j][1].toAscii() == '3' || list[j][1].toAscii() == '4' || list[j][1].toAscii() == '5' || list[j][1].toAscii() == '6' || list[j][1].toAscii() == '7' || list[j][1].toAscii() == '8' || list[j][1].toAscii() == '9' || list[j][1].toAscii() == '0')
						tmp_str.append(list[j][1]);
				a = tmp_str.toInt();

                                tmp_str = QString(list[j + 1][0]);
					if (list[j + 1][1].toAscii() == '1' || list[j + 1][1].toAscii() == '2' || list[j + 1][1].toAscii() == '3' || list[j + 1][1].toAscii() == '4' || list[j + 1][1].toAscii() == '5' || list[j + 1][1].toAscii() == '6' || list[j + 1][1].toAscii() == '7' || list[j + 1][1].toAscii() == '8' || list[j + 1][1].toAscii() == '9' || list[j + 1][1].toAscii() == '0')
						tmp_str.append(list[j + 1][1]);
				b = tmp_str.toInt();
				if (a > b) {
					tmp_str = list[j];
					list[j] = list[j + 1];
					list[j + 1] = tmp_str;
				}
			}
		}
	}

	//载入材质
	int i = 0, previous = 0;
	{
		QList<QPixmap> newlist;
		texture.append(newlist);
	}
	foreach (QString texname, list) {

		tmp_str = QString(texname[0]);
		if (texname[1].toAscii() == '1' || texname[1].toAscii() == '2' || texname[1].toAscii() == '3' || texname[1].toAscii() == '4' || texname[1].toAscii() == '5' || texname[1].toAscii() == '6' || texname[1].toAscii() == '7' || texname[1].toAscii() == '8' || texname[1].toAscii() == '9' || texname[1].toAscii() == '0') {
			tmp_str.append(texname[1]);
		}
		qDebug() << tmp_str;
		i = tmp_str.toInt();
		if (previous != i) {
			QList<QPixmap> newlist;
			texture.append(newlist);
			previous = i;
		}
		texture[previous].append(QPixmap(dir.absoluteFilePath(texname)));
	}
}

void Game::firstDataSubmit()
{
    qDebug()<<"hehe";
    QByteArray block;
    QDataStream out(&block,QIODevice::WriteOnly);

    QSettings settings("Funcatching Project", "Funcatching");
    settings.beginGroup("Player Name");
    player_name = settings.value("name").toString();
    settings.endGroup();

    out.setVersion(QDataStream::Qt_4_8);
    out<<quint32(0)<<player_name;//<<headImage;
    out.device()->seek(0);
    out<<quint32(block.size()-sizeof(quint16));
    tcpSocket.write(block);

    disconnect(&tcpSocket,SIGNAL(connected()),this,SLOT(firstDataSubmit()));
}

void initHeadPic()
{

}

void Game::getFirst()
{
    QDataStream in(&tcpSocket);
    in.setVersion(QDataStream::Qt_4_8);

    while(nextBlockSize==0){
        in >> nextBlockSize;
        if(nextBlockSize<tcpSocket.bytesAvailable())
            break;
    }
    unsigned short player_index;
    bool identity;
    unsigned short x,y,z;
    QString player_name;
    QImage *player_image = new QImage;

    in >> player_index;
    for(int i=0;i<=player_index;i++){
        in >>/* player_image >>*/ player_name >>identity >> x >> y >> z;
        storing_player *newPlayer;
        newPlayer->identety = identity;
        newPlayer->x = x;
        newPlayer->y = y;
        newPlayer->z = z;
        player.insert(i,newPlayer);
//        player_headImages->append(player_image);
    }
}
<|endoftext|>


<commit_before>#pragma GCC optimize ("-O3")

#include "libgame.h"
#include "storage.h"

#define _OUTPUT_INSTANCES
#include "games.h"
#undef _OUTPUT_INSTANCES

#define UP BITMASK(BUTTON_NE) | BITMASK(BUTTON_UP)
#define DOWN BITMASK(BUTTON_SE) | BITMASK(BUTTON_DOWN)
#define SELECT BITMASK(BUTTON_SW) | BITMASK(BUTTON_START)

// need some space for stack and system variables
#define AVAIL_SPACE 1024

static uint8_t N_GAMES;

static uint8_t sel = 0;

static uint8_t memory[AVAIL_SPACE];

static unsigned long cur_time = 0;

static unsigned long btn_timeout = 0;
#define BUTTON_DELAY 200

static bool game_running = false;
static bool btn_pressed = false;
static game_instance* ptr;
void prepare()
{
    N_GAMES = sizeof(instances) / sizeof(game_instance);
    game_setup();
    storage_init();
    game_set_ups(60);
}

void update(unsigned long delta)
{
    cur_time += delta;
    if (!game_running)
    {
        if (cur_time < btn_timeout) return;
        if ((game_is_any_button_pressed(DOWN)) && sel < (N_GAMES - 1))
        {
            sel++;
            btn_timeout = cur_time + BUTTON_DELAY;
        }
        if ((game_is_any_button_pressed(UP)) && sel > 0)
        {
            sel--;
            btn_timeout = cur_time + BUTTON_DELAY;
        }
        if (game_is_any_button_pressed(SELECT)) btn_pressed = true;
        if (!game_is_any_button_pressed(SELECT) && btn_pressed)
        {
            // run game
            ptr = instances + sel;
            game_running = true;
            *(ptr->data) = memory;
            ptr->prepare();
        }
    }
    else
    {
        ptr->update(delta);
    }
}

void render()
{
    if (!game_running)
    {
        for (uint8_t iter = 0; iter < N_GAMES; ++iter)
        {
            if (instances[iter].name)
            {
                game_draw_text(instances[iter].name, 0, 8 * iter, (iter == sel) ? RED : WHITE);
            }
        }
    }
    else
    {
        ptr->render();
    }
}

//////////////////////////
// Storage
//////////////////////////

void game_save(const void *buf, uint16_t size)
{
    storage_write((const char*)ptr->name, buf, size);
}

void game_load(void *buf, uint16_t size)
{
    storage_read((const char*)ptr->name, buf, size);
}

<commit_msg>Removed useless variables<commit_after>#pragma GCC optimize ("-O3")

#include "libgame.h"
#include "storage.h"

#define _OUTPUT_INSTANCES
#include "games.h"
#undef _OUTPUT_INSTANCES

#define UP BITMASK(BUTTON_NE) | BITMASK(BUTTON_UP)
#define DOWN BITMASK(BUTTON_SE) | BITMASK(BUTTON_DOWN)
#define SELECT BITMASK(BUTTON_SW) | BITMASK(BUTTON_START)

// need some space for stack and system variables
#define AVAIL_SPACE 1024

#define N_GAMES (sizeof(instances) / sizeof(game_instance))

static uint8_t sel = 0;

static uint8_t memory[AVAIL_SPACE];

static unsigned long cur_time = 0;

static unsigned long btn_timeout = 0;
#define BUTTON_DELAY 200

static bool btn_pressed = false;
static game_instance* ptr;
void prepare()
{
    game_setup();
    storage_init();
    game_set_ups(60);
}

void update(unsigned long delta)
{
    cur_time += delta;
    if (!ptr)
    {
        if (cur_time < btn_timeout) return;
        if ((game_is_any_button_pressed(DOWN)) && sel < (N_GAMES - 1))
        {
            sel++;
            btn_timeout = cur_time + BUTTON_DELAY;
        }
        if ((game_is_any_button_pressed(UP)) && sel > 0)
        {
            sel--;
            btn_timeout = cur_time + BUTTON_DELAY;
        }
        if (game_is_any_button_pressed(SELECT)) btn_pressed = true;
        if (!game_is_any_button_pressed(SELECT) && btn_pressed)
        {
            // run game
            ptr = instances + sel;
            *(ptr->data) = memory;
            ptr->prepare();
        }
    }
    else
    {
        ptr->update(delta);
    }
}

void render()
{
    if (!ptr)
    {
        for (uint8_t iter = 0; iter < N_GAMES; ++iter)
        {
            if (instances[iter].name)
            {
                game_draw_text(instances[iter].name, 0, 8 * iter, (iter == sel) ? RED : WHITE);
            }
        }
    }
    else
    {
        ptr->render();
    }
}

//////////////////////////
// Storage
//////////////////////////

void game_save(const void *buf, uint16_t size)
{
    storage_write((const char*)ptr->name, buf, size);
}

void game_load(void *buf, uint16_t size)
{
    storage_read((const char*)ptr->name, buf, size);
}

<|endoftext|>


<commit_before>/*
 * Eos - A 3D Morphable Model fitting library written in modern C++11/14.
 *
 * File: examples/fit-model.cpp
 *
 * Copyright 2015 Patrik Huber
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "eos/core/LandmarkMapper.hpp"
#include "eos/fitting/affine_camera_estimation.hpp"
#include "eos/fitting/linear_shape_fitting.hpp"
#include "eos/render/utils.hpp"
#include "eos/core/Landmark.hpp"

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"

#ifdef WIN32
	#define BOOST_ALL_DYN_LINK	// Link against the dynamic boost lib. Seems to be necessary because we use /MD, i.e. link to the dynamic CRT.
	#define BOOST_ALL_NO_LIB	// Don't use the automatic library linking by boost with VS2010 (#pragma ...). Instead, we specify everything in cmake.
#endif
#include "boost/program_options.hpp"
#include "boost/filesystem.hpp"

#include <vector>
#include <iostream>
#include <fstream>

using namespace eos;
namespace po = boost::program_options;
namespace fs = boost::filesystem;
using eos::core::Landmark;
using eos::core::LandmarkCollection;
using cv::Mat;
using cv::Vec2f;
using cv::Vec3f;
using cv::Vec4f;
using std::cout;
using std::endl;
using std::vector;
using std::string;

/**
 * Reads an ibug .pts landmark file and returns an ordered vector with
 * the 68 2D landmark coordinates.
 *
 * @param[in] filename Path to a .pts file.
 * @return An ordered vector with the 68 ibug landmarks.
 */
LandmarkCollection<cv::Vec2f> read_pts_landmarks(std::string filename)
{
	using std::getline;
	using cv::Vec2f;
	using std::string;
	LandmarkCollection<Vec2f> landmarks;
	landmarks.reserve(68);

	std::ifstream file(filename);
	if (!file.is_open()) {
		throw std::runtime_error(string("Could not open landmark file: " + filename));
	}

	string line;
	// Skip the first 3 lines, they're header lines:
	getline(file, line); // 'version: 1'
	getline(file, line); // 'n_points : 68'
	getline(file, line); // '{'

	int ibugId = 1;
	while (getline(file, line))
	{
		if (line == "}") { // end of the file
			break;
		}
		std::stringstream lineStream(line);

		Landmark<Vec2f> landmark;
		landmark.name = std::to_string(ibugId);
		if (!(lineStream >> landmark.coordinates[0] >> landmark.coordinates[1])) {
			throw std::runtime_error(string("Landmark format error while parsing the line: " + line));
		}
		// From the iBug website:
		// "Please note that the re-annotated data for this challenge are saved in the Matlab convention of 1 being
		// the first index, i.e. the coordinates of the top left pixel in an image are x=1, y=1."
		// ==> So we shift every point by 1:
		landmark.coordinates[0] -= 1.0f;
		landmark.coordinates[1] -= 1.0f;
		landmarks.emplace_back(landmark);
		++ibugId;
	}
	return landmarks;
};

/**
 * This app demonstrates estimation of the camera and fitting of the shape
 * model of a 3D Morphable Model from an ibug LFPW image with its landmarks.
 *
 * First, the 68 ibug landmarks are loaded from the .pts file and converted
 * to vertex indices using the LandmarkMapper. Then, an affine camera matrix
 * is estimated, and then, using this camera matrix, the shape is fitted
 * to the landmarks.
 */
int main(int argc, char *argv[])
{
	fs::path modelfile, isomapfile, imagefile, landmarksfile, mappingsfile, outputfile;
	try {
		po::options_description desc("Allowed options");
		desc.add_options()
			("help,h",
				"display the help message")
			("model,m", po::value<fs::path>(&modelfile)->required(),
				"a Morphable Model stored as cereal BinaryArchive")
			("image,i", po::value<fs::path>(&imagefile)->required()->default_value("data/image_0001.png"),
				"an input image")
			("landmarks,l", po::value<fs::path>(&landmarksfile)->required()->default_value("data/image_0001.pts"),
				"2D landmarks for the image, in ibug .pts format")
			("mapping,p", po::value<fs::path>(&mappingsfile)->required()->default_value("../share/ibug2did.txt"),
				"landmark identifier to model vertex number mapping")
			("output,o", po::value<fs::path>(&outputfile)->required()->default_value("out"),
				"basename for the output rendering and obj files")
			;
		po::variables_map vm;
		po::store(po::command_line_parser(argc, argv).options(desc).run(), vm);
		if (vm.count("help")) {
			cout << "Usage: fit-model [options]" << endl;
			cout << desc;
			return EXIT_SUCCESS;
		}
		po::notify(vm);
	}
	catch (const po::error& e) {
		cout << "Error while parsing command-line arguments: " << e.what() << endl;
		cout << "Use --help to display a list of options." << endl;
		return EXIT_SUCCESS;
	}

	// Load the image, landmarks, LandmarkMapper and the Morphable Model:
	Mat image = cv::imread(imagefile.string());
	auto landmarks = read_pts_landmarks(landmarksfile.string());
	morphablemodel::MorphableModel morphable_model = morphablemodel::load_model(modelfile.string());
	core::LandmarkMapper landmark_mapper = mappingsfile.empty() ? core::LandmarkMapper() : core::LandmarkMapper(mappingsfile);

	// Draw the loaded landmarks:
	Mat outimg = image.clone();
	for (auto&& lm : landmarks) {
		cv::rectangle(outimg, cv::Point2f(lm.coordinates[0] - 2.0f, lm.coordinates[1] - 2.0f), cv::Point2f(lm.coordinates[0] + 2.0f, lm.coordinates[1] + 2.0f), { 255, 0, 0 });
	}

	// Convert the landmarks to clip-space:
	std::for_each(begin(landmarks), end(landmarks), [&image](Landmark<Vec2f>& lm) { lm.coordinates = render::screen_to_clip_space(lm.coordinates, image.cols, image.rows); });

	// These will be the final 2D and 3D points used for the fitting:
	vector<Vec4f> model_points; // the points in the 3D shape model
	vector<int> vertex_indices; // their vertex indices
	vector<Vec2f> image_points; // the corresponding 2D landmark points

	// Sub-select all the landmarks which we have a mapping for (i.e. that are defined in the 3DMM):
	//std::transform(begin(landmarks), end(landmarks), begin(landmarks), [&landmark_mapper](const Landmark<Vec2f>& lm) {  });
	for (int i = 0; i < landmarks.size(); ++i) {
		auto converted_name = landmark_mapper.convert(landmarks[i].name);
		if (!converted_name) { // no mapping defined for the current landmark
			continue;
		}
		int vertex_idx = std::stoi(converted_name.get());
		Vec4f vertex = morphable_model.get_shape_model().get_mean_at_point(vertex_idx);
		model_points.emplace_back(vertex);
		vertex_indices.emplace_back(vertex_idx);
		image_points.emplace_back(landmarks[i].coordinates);
	}

	// Estimate the camera from the 2D - 3D point correspondences
	Mat affine_cam = fitting::estimate_affine_camera(image_points, model_points);

	// Draw the mean-face landmarks projected using the estimated camera:
	for (auto&& vertex : model_points) {
		Vec2f screen_point = fitting::project_affine(vertex, affine_cam, image.cols, image.rows);
		cv::circle(outimg, cv::Point2f(screen_point), 5, { 0.0f, 255.0f, 0.0f });
	}

	// Estimate the shape coefficients by fitting the shape to the landmarks:
	float lambda = 5.0f; // the regularisation parameter
	vector<float> fitted_coeffs = fitting::fit_shape_to_landmarks_linear(morphable_model, affine_cam, image_points, vertex_indices, lambda);

	// Obtain the full mesh and draw it using the estimated camera:
	render::Mesh mesh = morphable_model.draw_sample(fitted_coeffs, vector<float>());
	outputfile += fs::path(".obj");
	render::write_obj(mesh, outputfile.string()); // save the mesh as obj

	// Draw the projected points again, this time using the fitted model shape:
	for (auto&& idx : vertex_indices) {
		Vec4f model_point(mesh.vertices[idx][0], mesh.vertices[idx][1], mesh.vertices[idx][2], mesh.vertices[idx][3]);
		Vec2f screen_point = fitting::project_affine(model_point, affine_cam, image.cols, image.rows);
		cv::circle(outimg, cv::Point2f(screen_point), 3, { 0.0f, 0.0f, 255.0f });
	}

	// Save the output image:
	outputfile.replace_extension(".png");
	cv::imwrite(outputfile.string(), outimg);
	cout << "Finished fitting and wrote result image " << outputfile.string() << "." << endl;

	return EXIT_SUCCESS;
}
<commit_msg>Added try/catch to landmark and model loading<commit_after>/*
 * Eos - A 3D Morphable Model fitting library written in modern C++11/14.
 *
 * File: examples/fit-model.cpp
 *
 * Copyright 2015 Patrik Huber
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "eos/core/LandmarkMapper.hpp"
#include "eos/fitting/affine_camera_estimation.hpp"
#include "eos/fitting/linear_shape_fitting.hpp"
#include "eos/render/utils.hpp"
#include "eos/core/Landmark.hpp"

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"

#ifdef WIN32
	#define BOOST_ALL_DYN_LINK	// Link against the dynamic boost lib. Seems to be necessary because we use /MD, i.e. link to the dynamic CRT.
	#define BOOST_ALL_NO_LIB	// Don't use the automatic library linking by boost with VS2010 (#pragma ...). Instead, we specify everything in cmake.
#endif
#include "boost/program_options.hpp"
#include "boost/filesystem.hpp"

#include <vector>
#include <iostream>
#include <fstream>

using namespace eos;
namespace po = boost::program_options;
namespace fs = boost::filesystem;
using eos::core::Landmark;
using eos::core::LandmarkCollection;
using cv::Mat;
using cv::Vec2f;
using cv::Vec3f;
using cv::Vec4f;
using std::cout;
using std::endl;
using std::vector;
using std::string;

/**
 * Reads an ibug .pts landmark file and returns an ordered vector with
 * the 68 2D landmark coordinates.
 *
 * @param[in] filename Path to a .pts file.
 * @return An ordered vector with the 68 ibug landmarks.
 */
LandmarkCollection<cv::Vec2f> read_pts_landmarks(std::string filename)
{
	using std::getline;
	using cv::Vec2f;
	using std::string;
	LandmarkCollection<Vec2f> landmarks;
	landmarks.reserve(68);

	std::ifstream file(filename);
	if (!file.is_open()) {
		throw std::runtime_error(string("Could not open landmark file: " + filename));
	}

	string line;
	// Skip the first 3 lines, they're header lines:
	getline(file, line); // 'version: 1'
	getline(file, line); // 'n_points : 68'
	getline(file, line); // '{'

	int ibugId = 1;
	while (getline(file, line))
	{
		if (line == "}") { // end of the file
			break;
		}
		std::stringstream lineStream(line);

		Landmark<Vec2f> landmark;
		landmark.name = std::to_string(ibugId);
		if (!(lineStream >> landmark.coordinates[0] >> landmark.coordinates[1])) {
			throw std::runtime_error(string("Landmark format error while parsing the line: " + line));
		}
		// From the iBug website:
		// "Please note that the re-annotated data for this challenge are saved in the Matlab convention of 1 being
		// the first index, i.e. the coordinates of the top left pixel in an image are x=1, y=1."
		// ==> So we shift every point by 1:
		landmark.coordinates[0] -= 1.0f;
		landmark.coordinates[1] -= 1.0f;
		landmarks.emplace_back(landmark);
		++ibugId;
	}
	return landmarks;
};

/**
 * This app demonstrates estimation of the camera and fitting of the shape
 * model of a 3D Morphable Model from an ibug LFPW image with its landmarks.
 *
 * First, the 68 ibug landmarks are loaded from the .pts file and converted
 * to vertex indices using the LandmarkMapper. Then, an affine camera matrix
 * is estimated, and then, using this camera matrix, the shape is fitted
 * to the landmarks.
 */
int main(int argc, char *argv[])
{
	fs::path modelfile, isomapfile, imagefile, landmarksfile, mappingsfile, outputfile;
	try {
		po::options_description desc("Allowed options");
		desc.add_options()
			("help,h",
				"display the help message")
			("model,m", po::value<fs::path>(&modelfile)->required(),
				"a Morphable Model stored as cereal BinaryArchive")
			("image,i", po::value<fs::path>(&imagefile)->required()->default_value("data/image_0001.png"),
				"an input image")
			("landmarks,l", po::value<fs::path>(&landmarksfile)->required()->default_value("data/image_0001.pts"),
				"2D landmarks for the image, in ibug .pts format")
			("mapping,p", po::value<fs::path>(&mappingsfile)->required()->default_value("../share/ibug2did.txt"),
				"landmark identifier to model vertex number mapping")
			("output,o", po::value<fs::path>(&outputfile)->required()->default_value("out"),
				"basename for the output rendering and obj files")
			;
		po::variables_map vm;
		po::store(po::command_line_parser(argc, argv).options(desc).run(), vm);
		if (vm.count("help")) {
			cout << "Usage: fit-model [options]" << endl;
			cout << desc;
			return EXIT_SUCCESS;
		}
		po::notify(vm);
	}
	catch (const po::error& e) {
		cout << "Error while parsing command-line arguments: " << e.what() << endl;
		cout << "Use --help to display a list of options." << endl;
		return EXIT_SUCCESS;
	}

	// Load the image, landmarks, LandmarkMapper and the Morphable Model:
	Mat image = cv::imread(imagefile.string());
	LandmarkCollection<cv::Vec2f> landmarks;
	try {
		landmarks = read_pts_landmarks(landmarksfile.string());
	}
	catch (const std::runtime_error& e) {
		cout << "Error reading the landmarks: " << e.what() << endl;
		return EXIT_FAILURE;
	}
	morphablemodel::MorphableModel morphable_model;
	try {
		morphable_model = morphablemodel::load_model(modelfile.string());
	}
	catch (const std::runtime_error& e) {
		cout << "Error loading the Morphable Model: " << e.what() << endl;
		return EXIT_FAILURE;
	}
	core::LandmarkMapper landmark_mapper = mappingsfile.empty() ? core::LandmarkMapper() : core::LandmarkMapper(mappingsfile);

	// Draw the loaded landmarks:
	Mat outimg = image.clone();
	for (auto&& lm : landmarks) {
		cv::rectangle(outimg, cv::Point2f(lm.coordinates[0] - 2.0f, lm.coordinates[1] - 2.0f), cv::Point2f(lm.coordinates[0] + 2.0f, lm.coordinates[1] + 2.0f), { 255, 0, 0 });
	}

	// Convert the landmarks to clip-space:
	std::for_each(begin(landmarks), end(landmarks), [&image](Landmark<Vec2f>& lm) { lm.coordinates = render::screen_to_clip_space(lm.coordinates, image.cols, image.rows); });

	// These will be the final 2D and 3D points used for the fitting:
	vector<Vec4f> model_points; // the points in the 3D shape model
	vector<int> vertex_indices; // their vertex indices
	vector<Vec2f> image_points; // the corresponding 2D landmark points

	// Sub-select all the landmarks which we have a mapping for (i.e. that are defined in the 3DMM):
	//std::transform(begin(landmarks), end(landmarks), begin(landmarks), [&landmark_mapper](const Landmark<Vec2f>& lm) {  });
	for (int i = 0; i < landmarks.size(); ++i) {
		auto converted_name = landmark_mapper.convert(landmarks[i].name);
		if (!converted_name) { // no mapping defined for the current landmark
			continue;
		}
		int vertex_idx = std::stoi(converted_name.get());
		Vec4f vertex = morphable_model.get_shape_model().get_mean_at_point(vertex_idx);
		model_points.emplace_back(vertex);
		vertex_indices.emplace_back(vertex_idx);
		image_points.emplace_back(landmarks[i].coordinates);
	}

	// Estimate the camera from the 2D - 3D point correspondences
	Mat affine_cam = fitting::estimate_affine_camera(image_points, model_points);

	// Draw the mean-face landmarks projected using the estimated camera:
	for (auto&& vertex : model_points) {
		Vec2f screen_point = fitting::project_affine(vertex, affine_cam, image.cols, image.rows);
		cv::circle(outimg, cv::Point2f(screen_point), 5, { 0.0f, 255.0f, 0.0f });
	}

	// Estimate the shape coefficients by fitting the shape to the landmarks:
	float lambda = 5.0f; // the regularisation parameter
	vector<float> fitted_coeffs = fitting::fit_shape_to_landmarks_linear(morphable_model, affine_cam, image_points, vertex_indices, lambda);

	// Obtain the full mesh and draw it using the estimated camera:
	render::Mesh mesh = morphable_model.draw_sample(fitted_coeffs, vector<float>());
	outputfile += fs::path(".obj");
	render::write_obj(mesh, outputfile.string()); // save the mesh as obj

	// Draw the projected points again, this time using the fitted model shape:
	for (auto&& idx : vertex_indices) {
		Vec4f model_point(mesh.vertices[idx][0], mesh.vertices[idx][1], mesh.vertices[idx][2], mesh.vertices[idx][3]);
		Vec2f screen_point = fitting::project_affine(model_point, affine_cam, image.cols, image.rows);
		cv::circle(outimg, cv::Point2f(screen_point), 3, { 0.0f, 0.0f, 255.0f });
	}

	// Save the output image:
	outputfile.replace_extension(".png");
	cv::imwrite(outputfile.string(), outimg);
	cout << "Finished fitting and wrote result image " << outputfile.string() << "." << endl;

	return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before><commit_msg>v.1.70.2.1 bug fixed for jpeg writer and reader<commit_after><|endoftext|>


<commit_before>/*
 * rewrite - string rewriting functions through sed coproc. - implementation
 * Copyright(c) 2004 of wave++ (Yuri D'Elia)
 * Distributed under GNU LGPL without ANY warranty.
 *
 * Note: we exploit here the -u (unbuffered) flag of GNU sed in order to avoid
 * fiddling with ptys and termio. This limitation should probably be removed.
 * The code looked so clean... *eeh*.
 */

// interface
#include "fIcy.hh"
#include "rewrite.hh"
using std::string;

#include <cstring>
using std::memcpy;

#include <stdexcept>
using std::runtime_error;

// c system headers
#include <unistd.h>
#include <sys/wait.h>

Rewrite::Rewrite(const char* script)
{
  // no script specified
  if(!script)
  {
    pid = -1;
    return;
  }

  // create two pipes
  if((pipe(in) < 0) || (pipe(out) < 0))
    throw runtime_error("cannot create pipes");

  pid = fork();
  if(pid < 0)
    throw runtime_error("cannot fork");

  if(pid)
  {
    // close unneeded ends
    close(in[1]);
    close(out[0]);
  }
  else
  {
    // close undeeded ends
    close(in[0]);
    close(out[1]);

    // remap descriptors
    if((dup2(in[1], STDOUT_FILENO) < 0) ||
	(dup2(out[0], STDIN_FILENO) < 0))
      throw runtime_error("cannot remap descriptors");

    // execute the coprocess
    execlp(fIcy::sed, fIcy::sed, "-u", "-f", script, NULL);
    throw runtime_error(string("cannot execute ") + fIcy::sed);
  }
}

Rewrite::~Rewrite() throw()
{
  // no filter specified, return immediately
  if(pid < 0)
    return;

  // close and wait
  close(in[0]);
  close(out[1]);
  waitpid(pid, NULL, 0);
}

void
Rewrite::operator()(string& buf)
{
  // no filter specified, return immediately
  if(pid < 0)
    return;

  // write to the coprocess
  char c = '\n';
  write(out[1], buf.data(), buf.size());
  if(write(out[1], &c, 1) < 0)
    throw runtime_error("cannot write to the coprocess");

  // read from the coprocess
  buf.clear();
  for(c = 0; c != '\n'; buf += c)
  {
    if(read(in[0], &c, 1) < 0)
      throw runtime_error("cannot read from the coprocess");
  }
}
<commit_msg>Last '\n' was not removed.<commit_after>/*
 * rewrite - string rewriting functions through sed coproc. - implementation
 * Copyright(c) 2004 of wave++ (Yuri D'Elia)
 * Distributed under GNU LGPL without ANY warranty.
 *
 * Note: we exploit here the -u (unbuffered) flag of GNU sed in order to avoid
 * fiddling with ptys and termio. This limitation should probably be removed.
 * The code looked so clean... *eeh*.
 */

// interface
#include "fIcy.hh"
#include "rewrite.hh"
using std::string;

#include <cstring>
using std::memcpy;

#include <stdexcept>
using std::runtime_error;

// c system headers
#include <unistd.h>
#include <sys/wait.h>

Rewrite::Rewrite(const char* script)
{
  // no script specified
  if(!script)
  {
    pid = -1;
    return;
  }

  // create two pipes
  if((pipe(in) < 0) || (pipe(out) < 0))
    throw runtime_error("cannot create pipes");

  pid = fork();
  if(pid < 0)
    throw runtime_error("cannot fork");

  if(pid)
  {
    // close unneeded ends
    close(in[1]);
    close(out[0]);
  }
  else
  {
    // close undeeded ends
    close(in[0]);
    close(out[1]);

    // remap descriptors
    if((dup2(in[1], STDOUT_FILENO) < 0) ||
	(dup2(out[0], STDIN_FILENO) < 0))
      throw runtime_error("cannot remap descriptors");

    // execute the coprocess
    execlp(fIcy::sed, fIcy::sed, "-u", "-f", script, NULL);
    throw runtime_error(string("cannot execute ") + fIcy::sed);
  }
}

Rewrite::~Rewrite() throw()
{
  // no filter specified, return immediately
  if(pid < 0)
    return;

  // close and wait
  close(in[0]);
  close(out[1]);
  waitpid(pid, NULL, 0);
}

void
Rewrite::operator()(string& buf)
{
  // no filter specified, return immediately
  if(pid < 0)
    return;

  // write to the coprocess
  char c = '\n';
  write(out[1], buf.data(), buf.size());
  if(write(out[1], &c, 1) < 0)
    throw runtime_error("cannot write to the coprocess");

  // read from the coprocess
  buf.clear();
  for(;; buf += c)
  {
    if(read(in[0], &c, 1) < 0)
      throw runtime_error("cannot read from the coprocess");
    if(c == '\n')
      break;
  }
}
<|endoftext|>


<commit_before>/**********************************************************************
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.osgeo.org
 *
 * Copyright (C) 2012 Excensus LLC.
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Licence as published
 * by the Free Software Foundation.
 * See the COPYING file for more information.
 *
 **********************************************************************
 *
 * Last port: triangulate/VoronoiDiagramBuilder.java rev. r524
 *
 **********************************************************************/

#include <geos/triangulate/VoronoiDiagramBuilder.h>

#include <algorithm>
#include <math.h>
#include <vector>
#include <iostream>

#include <geos/geom/GeometryFactory.h>
#include <geos/geom/Coordinate.h>
#include <geos/geom/Envelope.h>
#include <geos/geom/CoordinateSequence.h>
#include <geos/triangulate/IncrementalDelaunayTriangulator.h>
#include <geos/triangulate/DelaunayTriangulationBuilder.h>
#include <geos/triangulate/quadedge/QuadEdgeSubdivision.h>
#include <geos/operation/valid/RepeatedPointRemover.h>
#include <geos/util.h>

using geos::detail::make_unique;

namespace geos {
namespace triangulate { //geos.triangulate

using namespace geos::geom;

VoronoiDiagramBuilder::VoronoiDiagramBuilder() :
    tolerance(0.0), clipEnv(nullptr)
{
}

VoronoiDiagramBuilder::~VoronoiDiagramBuilder()
{
}

void
VoronoiDiagramBuilder::setSites(const geom::Geometry& geom)
{
    siteCoords = DelaunayTriangulationBuilder::extractUniqueCoordinates(geom);
}

void
VoronoiDiagramBuilder::setSites(const geom::CoordinateSequence& coords)
{
    siteCoords = operation::valid::RepeatedPointRemover::removeRepeatedPoints(&coords);
}

void
VoronoiDiagramBuilder::setClipEnvelope(const geom::Envelope* nClipEnv)
{
    clipEnv = nClipEnv;
}

void
VoronoiDiagramBuilder::setTolerance(double nTolerance)
{
    tolerance = nTolerance;
}

void
VoronoiDiagramBuilder::create()
{
    if(subdiv.get()) {
        return;
    }

    diagramEnv = DelaunayTriangulationBuilder::envelope(*siteCoords);
    //adding buffer around the final envelope
    double expandBy = std::max(diagramEnv.getWidth(), diagramEnv.getHeight());
    diagramEnv.expandBy(expandBy);
    if(clipEnv) {
        diagramEnv.expandToInclude(clipEnv);
    }

    auto vertices = DelaunayTriangulationBuilder::toVertices(*siteCoords);
    std::sort(vertices.begin(), vertices.end()); // Best performance from locator when inserting points near each other

    subdiv.reset(new quadedge::QuadEdgeSubdivision(diagramEnv, tolerance));
    IncrementalDelaunayTriangulator triangulator(subdiv.get());
    triangulator.insertSites(vertices);
}

std::unique_ptr<quadedge::QuadEdgeSubdivision>
VoronoiDiagramBuilder::getSubdivision()
{
    create();
    // NOTE: Apparently, this is 'source' method giving up the object resource.
    return std::move(subdiv);
}

std::unique_ptr<geom::GeometryCollection>
VoronoiDiagramBuilder::getDiagram(const geom::GeometryFactory& geomFact)
{
    create();

    auto polys = subdiv->getVoronoiCellPolygons(geomFact);
    auto ret = clipGeometryCollection(polys, diagramEnv);

    if (ret == nullptr) {
        return std::unique_ptr<geom::GeometryCollection>(geomFact.createGeometryCollection());
    }

    return ret;
}

std::unique_ptr<geom::Geometry>
VoronoiDiagramBuilder::getDiagramEdges(const geom::GeometryFactory& geomFact)
{
    create();
    std::unique_ptr<geom::MultiLineString> edges = subdiv->getVoronoiDiagramEdges(geomFact);
    if(edges->isEmpty()) {
        return std::unique_ptr<Geometry>(edges.release());
    }
    std::unique_ptr<geom::Geometry> clipPoly(geomFact.toGeometry(&diagramEnv));
    std::unique_ptr<Geometry> clipped(clipPoly->intersection(edges.get()));
    return clipped;
}

std::unique_ptr<geom::GeometryCollection>
VoronoiDiagramBuilder::clipGeometryCollection(std::vector<std::unique_ptr<Geometry>> & geoms, const geom::Envelope& clipEnv)
{
    if (geoms.empty()) {
        return nullptr;
    }

    auto gfact = geoms[0]->getFactory();

    std::unique_ptr<geom::Geometry> clipPoly(gfact->toGeometry(&clipEnv));
    auto clipped = make_unique<std::vector<Geometry*>>();

    for(auto& g : geoms) {
        std::unique_ptr<Geometry> result;

        // don't clip unless necessary
        if(clipEnv.contains(g->getEnvelopeInternal())) {
            result = std::move(g);
            // TODO: check if userData is correctly cloned here?
        }
        else if(clipEnv.intersects(g->getEnvelopeInternal())) {
            result = clipPoly->intersection(g.get());
            result->setUserData(g->getUserData()); // TODO: needed ?
        }

        if(result.get() && !result->isEmpty()) {
            clipped->push_back(result.release());
        }
    }

    return std::unique_ptr<GeometryCollection>(gfact->createGeometryCollection(clipped.release()));
}

} //namespace geos.triangulate
} //namespace geos
<commit_msg>Avoid a heap alloc / raw pointer usage<commit_after>/**********************************************************************
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.osgeo.org
 *
 * Copyright (C) 2012 Excensus LLC.
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Licence as published
 * by the Free Software Foundation.
 * See the COPYING file for more information.
 *
 **********************************************************************
 *
 * Last port: triangulate/VoronoiDiagramBuilder.java rev. r524
 *
 **********************************************************************/

#include <geos/triangulate/VoronoiDiagramBuilder.h>

#include <algorithm>
#include <math.h>
#include <vector>
#include <iostream>

#include <geos/geom/GeometryFactory.h>
#include <geos/geom/Coordinate.h>
#include <geos/geom/Envelope.h>
#include <geos/geom/CoordinateSequence.h>
#include <geos/triangulate/IncrementalDelaunayTriangulator.h>
#include <geos/triangulate/DelaunayTriangulationBuilder.h>
#include <geos/triangulate/quadedge/QuadEdgeSubdivision.h>
#include <geos/operation/valid/RepeatedPointRemover.h>
#include <geos/util.h>

using geos::detail::make_unique;

namespace geos {
namespace triangulate { //geos.triangulate

using namespace geos::geom;

VoronoiDiagramBuilder::VoronoiDiagramBuilder() :
    tolerance(0.0), clipEnv(nullptr)
{
}

VoronoiDiagramBuilder::~VoronoiDiagramBuilder()
{
}

void
VoronoiDiagramBuilder::setSites(const geom::Geometry& geom)
{
    siteCoords = DelaunayTriangulationBuilder::extractUniqueCoordinates(geom);
}

void
VoronoiDiagramBuilder::setSites(const geom::CoordinateSequence& coords)
{
    siteCoords = operation::valid::RepeatedPointRemover::removeRepeatedPoints(&coords);
}

void
VoronoiDiagramBuilder::setClipEnvelope(const geom::Envelope* nClipEnv)
{
    clipEnv = nClipEnv;
}

void
VoronoiDiagramBuilder::setTolerance(double nTolerance)
{
    tolerance = nTolerance;
}

void
VoronoiDiagramBuilder::create()
{
    if(subdiv.get()) {
        return;
    }

    diagramEnv = DelaunayTriangulationBuilder::envelope(*siteCoords);
    //adding buffer around the final envelope
    double expandBy = std::max(diagramEnv.getWidth(), diagramEnv.getHeight());
    diagramEnv.expandBy(expandBy);
    if(clipEnv) {
        diagramEnv.expandToInclude(clipEnv);
    }

    auto vertices = DelaunayTriangulationBuilder::toVertices(*siteCoords);
    std::sort(vertices.begin(), vertices.end()); // Best performance from locator when inserting points near each other

    subdiv.reset(new quadedge::QuadEdgeSubdivision(diagramEnv, tolerance));
    IncrementalDelaunayTriangulator triangulator(subdiv.get());
    triangulator.insertSites(vertices);
}

std::unique_ptr<quadedge::QuadEdgeSubdivision>
VoronoiDiagramBuilder::getSubdivision()
{
    create();
    // NOTE: Apparently, this is 'source' method giving up the object resource.
    return std::move(subdiv);
}

std::unique_ptr<geom::GeometryCollection>
VoronoiDiagramBuilder::getDiagram(const geom::GeometryFactory& geomFact)
{
    create();

    auto polys = subdiv->getVoronoiCellPolygons(geomFact);
    auto ret = clipGeometryCollection(polys, diagramEnv);

    if (ret == nullptr) {
        return std::unique_ptr<geom::GeometryCollection>(geomFact.createGeometryCollection());
    }

    return ret;
}

std::unique_ptr<geom::Geometry>
VoronoiDiagramBuilder::getDiagramEdges(const geom::GeometryFactory& geomFact)
{
    create();
    std::unique_ptr<geom::MultiLineString> edges = subdiv->getVoronoiDiagramEdges(geomFact);
    if(edges->isEmpty()) {
        return std::unique_ptr<Geometry>(edges.release());
    }
    std::unique_ptr<geom::Geometry> clipPoly(geomFact.toGeometry(&diagramEnv));
    std::unique_ptr<Geometry> clipped(clipPoly->intersection(edges.get()));
    return clipped;
}

std::unique_ptr<geom::GeometryCollection>
VoronoiDiagramBuilder::clipGeometryCollection(std::vector<std::unique_ptr<Geometry>> & geoms, const geom::Envelope& clipEnv)
{
    if (geoms.empty()) {
        return nullptr;
    }

    auto gfact = geoms[0]->getFactory();

    std::unique_ptr<geom::Geometry> clipPoly(gfact->toGeometry(&clipEnv));
    std::vector<std::unique_ptr<Geometry>> clipped;

    for(auto& g : geoms) {
        // don't clip unless necessary
        if(clipEnv.contains(g->getEnvelopeInternal())) {
            clipped.push_back(std::move(g));
            // TODO: check if userData is correctly cloned here?
        } else if(clipEnv.intersects(g->getEnvelopeInternal())) {
            auto result = clipPoly->intersection(g.get());
            result->setUserData(g->getUserData()); // TODO: needed ?
            if (!result->isEmpty()) {
                clipped.push_back(std::move(result));
            }
        }
    }

    return gfact->createGeometryCollection(std::move(clipped));
}

} //namespace geos.triangulate
} //namespace geos
<|endoftext|>


<commit_before>#ifndef __UNIVERSE_STRUCT_HPP_INCLUDED
#define __UNIVERSE_STRUCT_HPP_INCLUDED

// Include standard headers
#include <stdint.h> // uint32_t etc.
#include <string>   // std::string

typedef struct UniverseStruct
{
    UniverseStruct()
        : window_width(1600),
        window_height(900),
        window_title("Ylikuutio 0.0.1"),
        is_headless(false),
        text_size(40),
        font_size(16),
        max_FPS(50000),        // default value max 50000 frames per second.
        speed(5.0f),           // default value 5.0 units / second
        mouse_speed(0.005f),
        gravity(9.81f / 60.0f),
        znear(1.0f),
        zfar(5000.0f) // visibility: 5000 units.
    {
        // constructor.
    }

    int32_t window_width;
    int32_t window_height;
    std::string window_title;
    bool is_headless;
    int32_t text_size;
    int32_t font_size;
    uint32_t max_FPS;
    float speed;
    float mouse_speed;
    float gravity;
    float znear;
    float zfar;
} UniverseStruct;

#endif
<commit_msg>`typedef struct UniverseStruct`: reorder fields.<commit_after>#ifndef __UNIVERSE_STRUCT_HPP_INCLUDED
#define __UNIVERSE_STRUCT_HPP_INCLUDED

// Include standard headers
#include <stdint.h> // uint32_t etc.
#include <string>   // std::string

typedef struct UniverseStruct
{
    UniverseStruct()
        : window_title("Ylikuutio 0.0.1"),
        window_width(1600),
        window_height(900),
        text_size(40),
        font_size(16),
        max_FPS(50000),        // default value max 50000 frames per second.
        speed(5.0f),           // default value 5.0 units / second
        mouse_speed(0.005f),
        gravity(9.81f / 60.0f),
        znear(1.0f),
        zfar(5000.0f), // visibility: 5000 units.
        is_headless(false)
    {
        // constructor.
    }

    std::string window_title;
    int32_t window_width;
    int32_t window_height;
    int32_t text_size;
    int32_t font_size;
    uint32_t max_FPS;
    float speed;
    float mouse_speed;
    float gravity;
    float znear;
    float zfar;
    bool is_headless;
} UniverseStruct;

#endif
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "Connection.h"
#include "NetUtils.h"

#include <iostream>
#include <stdexcept>
#include <cstring>

namespace CoAP {

// Multicast "All CoAP Nodes" Address
// for IPv4: 224.0.1.187
// for IPv6: link-local scoped address ff02::fd and the site-local scoped address ff05::fd
void Connection::open(uint16_t port) {
  if (socket_ != 0) throw std::logic_error("Cannot open already open connection.");

  socket_ = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  struct sockaddr_in sa;
  if (socket_ == 0) {
    perror("creating socket failed");
    exit(EXIT_FAILURE);
  }

  const int32_t timeoutInMS = 100;
  timeval timeout{timeoutInMS / 1000, (timeoutInMS % 1000) * 1000};
  if (-1 == setsockopt(socket_, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout))) {
    perror("setting receive timeout on socket failed");
    close(socket_);
    exit(EXIT_FAILURE);
  }

  auto const WITH_MULTICAST = true;
  if (WITH_MULTICAST) {
    // enable multicast messages to be sent back to the local host
    u_char loop = 1;
    if (-1 == setsockopt(socket_, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop))) {
      perror("setting multicast loopback on socket failed");
      close(socket_);
      exit(EXIT_FAILURE);
    }

    // joining a multicast group
    ip_mreq mreq;
    mreq.imr_interface.s_addr = INADDR_ANY;
    mreq.imr_multiaddr.s_addr = inet_addr("224.0.1.187");
    if (-1 == setsockopt(socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))) {
      perror("setting multicast membership on socket failed");
      close(socket_);
      exit(EXIT_FAILURE);
    }
  }

  memset(&sa, 0, sizeof sa);
  sa.sin_family = AF_INET;
  sa.sin_addr.s_addr = htonl(INADDR_ANY);
  sa.sin_port = htons(port);

  // TODO: Throw exception if bind fails
  if (-1 == bind(socket_, (struct sockaddr*) &sa, sizeof(sa))) {
    throw(std::runtime_error("bind failed"));
  }
}

void Connection::send(Telegram&& telegram) {
  if (socket_ == 0) throw std::logic_error("Cannot send on connection if it is not open.");

  struct sockaddr_in sa;

  memset(&sa, 0, sizeof sa);
  sa.sin_family = AF_INET;
  sa.sin_addr.s_addr = telegram.getIP();
  sa.sin_port = htons(telegram.getPort());

  // TODO: How can we replace this temporary copy, e.g. by a move or reference
  auto msg = telegram.getMessage();
  auto bytes_sent = sendto(socket_, msg.data(), msg.size(), 0, (struct sockaddr*) &sa, sizeof(sa));
  if (bytes_sent < 0) {
    // TODO: Throw a better exception if send fails
    printf("Error sending packet: %s\n", strerror(errno));
    exit(EXIT_FAILURE);
  }
}

Optional<Telegram> Connection::get() {
  if (socket_ == 0) throw std::logic_error("Cannot send on connection if it is not open.");

  struct sockaddr_in sa;
  socklen_t fromlen = sizeof(sa);
  memset(&sa, 0, sizeof(sa));
  ssize_t bytesReceived = recvfrom(socket_, buffer_, bufferSize_, 0, (struct sockaddr*) &sa, &fromlen);
  // TODO: Throw exception if receive failed
  if (bytesReceived < 0) {
    if (errno == EAGAIN) return Optional<Telegram>();
    fprintf(stderr, "%s\n", strerror(errno));
    exit(EXIT_FAILURE);
  }
  return Optional<Telegram>(sa.sin_addr.s_addr, ntohs(sa.sin_port), std::vector<uint8_t>(buffer_, buffer_+bytesReceived));
}

int Connection::socket(int domain, int type, int protocol) const {
  return ::socket(domain, type, protocol);
}

int Connection::setsockopt(int socket, int level, int option_name,
                           const void* option_value, socklen_t option_len) const {
  return ::setsockopt(socket, level, option_name, option_value, option_len);
}

int Connection::bind(int socket, const struct sockaddr* address, socklen_t address_len) const {
  return ::bind(socket, address, address_len);
}
}  // namespace CoAP
<commit_msg>Disabled multicast by default<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "Connection.h"
#include "NetUtils.h"

#include <iostream>
#include <stdexcept>
#include <cstring>

namespace CoAP {

// Multicast "All CoAP Nodes" Address
// for IPv4: 224.0.1.187
// for IPv6: link-local scoped address ff02::fd and the site-local scoped address ff05::fd
void Connection::open(uint16_t port) {
  if (socket_ != 0) throw std::logic_error("Cannot open already open connection.");

  socket_ = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  struct sockaddr_in sa;
  if (socket_ == 0) {
    perror("creating socket failed");
    exit(EXIT_FAILURE);
  }

  const int32_t timeoutInMS = 100;
  timeval timeout{timeoutInMS / 1000, (timeoutInMS % 1000) * 1000};
  if (-1 == setsockopt(socket_, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout))) {
    perror("setting receive timeout on socket failed");
    close(socket_);
    exit(EXIT_FAILURE);
  }

  auto constexpr WITH_MULTICAST = false;
  if (WITH_MULTICAST) {
    // enable multicast messages to be sent back to the local host
    u_char loop = 1;
    if (-1 == setsockopt(socket_, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop))) {
      perror("setting multicast loopback on socket failed");
      close(socket_);
      exit(EXIT_FAILURE);
    }

    // joining a multicast group
    ip_mreq mreq;
    mreq.imr_interface.s_addr = INADDR_ANY;
    mreq.imr_multiaddr.s_addr = inet_addr("224.0.1.187");
    if (-1 == setsockopt(socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))) {
      perror("setting multicast membership on socket failed");
      close(socket_);
      exit(EXIT_FAILURE);
    }
  }

  memset(&sa, 0, sizeof sa);
  sa.sin_family = AF_INET;
  sa.sin_addr.s_addr = htonl(INADDR_ANY);
  sa.sin_port = htons(port);

  // TODO: Throw exception if bind fails
  if (-1 == bind(socket_, (struct sockaddr*) &sa, sizeof(sa))) {
    throw(std::runtime_error("bind failed"));
  }
}

void Connection::send(Telegram&& telegram) {
  if (socket_ == 0) throw std::logic_error("Cannot send on connection if it is not open.");

  struct sockaddr_in sa;

  memset(&sa, 0, sizeof sa);
  sa.sin_family = AF_INET;
  sa.sin_addr.s_addr = telegram.getIP();
  sa.sin_port = htons(telegram.getPort());

  // TODO: How can we replace this temporary copy, e.g. by a move or reference
  auto msg = telegram.getMessage();
  auto bytes_sent = sendto(socket_, msg.data(), msg.size(), 0, (struct sockaddr*) &sa, sizeof(sa));
  if (bytes_sent < 0) {
    // TODO: Throw a better exception if send fails
    printf("Error sending packet: %s\n", strerror(errno));
    exit(EXIT_FAILURE);
  }
}

Optional<Telegram> Connection::get() {
  if (socket_ == 0) throw std::logic_error("Cannot send on connection if it is not open.");

  struct sockaddr_in sa;
  socklen_t fromlen = sizeof(sa);
  memset(&sa, 0, sizeof(sa));
  ssize_t bytesReceived = recvfrom(socket_, buffer_, bufferSize_, 0, (struct sockaddr*) &sa, &fromlen);
  // TODO: Throw exception if receive failed
  if (bytesReceived < 0) {
    if (errno == EAGAIN) return Optional<Telegram>();
    fprintf(stderr, "%s\n", strerror(errno));
    exit(EXIT_FAILURE);
  }
  return Optional<Telegram>(sa.sin_addr.s_addr, ntohs(sa.sin_port), std::vector<uint8_t>(buffer_, buffer_+bytesReceived));
}

int Connection::socket(int domain, int type, int protocol) const {
  return ::socket(domain, type, protocol);
}

int Connection::setsockopt(int socket, int level, int option_name,
                           const void* option_value, socklen_t option_len) const {
  return ::setsockopt(socket, level, option_name, option_value, option_len);
}

int Connection::bind(int socket, const struct sockaddr* address, socklen_t address_len) const {
  return ::bind(socket, address, address_len);
}
}  // namespace CoAP
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2005, Peter Sommerlad and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

//--- interface include --------------------------------------------------------
#include "Action.h"

//--- standard modules used ----------------------------------------------------
#include "Registry.h"
#include "Page.h"
#include "Dbg.h"

//---- ActionsModule -----------------------------------------------------------
RegisterModule(ActionsModule);

ActionsModule::ActionsModule(const char *name) : WDModule(name)
{
}

ActionsModule::~ActionsModule()
{
}

bool ActionsModule::Init(const ROAnything config)
{
	if (config.IsDefined("Actions")) {
		AliasInstaller ai("Action");
		return RegisterableObject::Install(config["Actions"], "Action", &ai);
	}
	return false;
}

bool ActionsModule::ResetFinis(const ROAnything )
{
	AliasTerminator at("Action");
	return RegisterableObject::ResetTerminate("Action", &at);
}

bool ActionsModule::Finis()
{
	return StdFinis("Action", "Actions");
}

//---- Action ----------------------------------------------------------
//RegisterObject(Action, Action); no objects of the abstract type
Action::Action(const char *name) : NotCloned(name)
{
}

bool Action::ExecAction(String &transitionToken, Context &c)
{
	StartTrace1(Action.ExecAction, "<" << transitionToken << ">");
	return ExecAction(transitionToken, c, ROAnything());
}

bool Action::ExecAction(String &transitionToken, Context &c, const ROAnything &config)
{
	StartTrace1(Action.ExecAction, "<" << transitionToken << ">");
	bool result(false);
	switch (config.GetType()) {
		case AnyArrayType: {
			long sz = config.GetSize();
			for (long i = 0; i < sz; ++i) {
				String slotname = config.SlotName(i);
				if (slotname.Length() > 0) {
					result = CallAction(slotname, transitionToken, c, config[i]);
				} else {
					result = ExecAction(transitionToken, c, config[i]);
				}
				if ( !result ) {
					return result;
				}
			}
		}
		break;

		case AnyCharPtrType:
			transitionToken = config.AsString();
			result = CallAction(transitionToken, transitionToken, c, ROAnything());
			break;

		default:
			result = CallAction(transitionToken, transitionToken, c, config);
	}
	// it is not a valid action
	return result;
}

bool Action::CallAction(String &actionName, String &transitionToken, Context &c, const ROAnything &config)
{
	StartTrace1(Action.CallAction, "<" << actionName << "/" << transitionToken << ">");

	if (actionName.Length() > 0) {
		Action *a = FindAction(actionName);
		if (a) {
			return a->DoExecAction(transitionToken, c, config);
		} else if (!config.IsNull()) {
			return ExecAction(transitionToken, c, config);
		}
		return true;
	}
	return false;
}

RegCacheImpl(Action);	// FindAction()

//---- PreprocessAction ----------------------------------------------------------------------
class EXPORTDECL_WDBASE PreprocessAction : public Action
{
public:
	PreprocessAction(const char *name);

	virtual bool DoAction(String &action, Context &);
};

RegisterAction(PreprocessAction);
PreprocessAction::PreprocessAction(const char *name) : Action(name)
{
}

bool PreprocessAction::DoAction(String &action, Context &c)
{
	StartTrace1(PreprocessAction.DoAction, "<" << action << ">");
	Page *s = c.GetPage();

	if ( s ) {
		s->Preprocess(c);
	}
	return true;
}
<commit_msg>changed StartTrace to StatTrace<commit_after>/*
 * Copyright (c) 2005, Peter Sommerlad and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

//--- interface include --------------------------------------------------------
#include "Action.h"

//--- standard modules used ----------------------------------------------------
#include "Registry.h"
#include "Page.h"
#include "Dbg.h"

//---- ActionsModule -----------------------------------------------------------
RegisterModule(ActionsModule);

ActionsModule::ActionsModule(const char *name) : WDModule(name)
{
}

ActionsModule::~ActionsModule()
{
}

bool ActionsModule::Init(const ROAnything config)
{
	if (config.IsDefined("Actions")) {
		AliasInstaller ai("Action");
		return RegisterableObject::Install(config["Actions"], "Action", &ai);
	}
	return false;
}

bool ActionsModule::ResetFinis(const ROAnything )
{
	AliasTerminator at("Action");
	return RegisterableObject::ResetTerminate("Action", &at);
}

bool ActionsModule::Finis()
{
	return StdFinis("Action", "Actions");
}

//---- Action ----------------------------------------------------------
//RegisterObject(Action, Action); no objects of the abstract type
Action::Action(const char *name) : NotCloned(name)
{
}

bool Action::ExecAction(String &transitionToken, Context &c)
{
	StatTrace(Action.ExecAction, "<" << transitionToken << ">", Storage::Current());
	return ExecAction(transitionToken, c, ROAnything());
}

bool Action::ExecAction(String &transitionToken, Context &c, const ROAnything &config)
{
	StatTrace(Action.ExecAction, "<" << transitionToken << ">", Storage::Current());
	bool result(false);
	switch (config.GetType()) {
		case AnyArrayType: {
			String slotname( 32L );
			for (long i = 0, sz = config.GetSize(); i < sz; ++i) {
				slotname = config.SlotName(i);
				if (slotname.Length() > 0) {
					result = CallAction(slotname, transitionToken, c, config[i]);
				} else {
					result = ExecAction(transitionToken, c, config[i]);
				}
				if ( !result ) {
					return result;
				}
			}
		}
		break;

		case AnyCharPtrType:
			transitionToken = config.AsString();
			result = CallAction(transitionToken, transitionToken, c, ROAnything());
			break;

		default:
			result = CallAction(transitionToken, transitionToken, c, config);
	}
	// it is not a valid action
	return result;
}

bool Action::CallAction(String &actionName, String &transitionToken, Context &c, const ROAnything &config)
{
	StatTrace(Action.CallAction, "<" << actionName << "/" << transitionToken << ">", Storage::Current());
	if (actionName.Length() > 0) {
		Action *a( FindAction(actionName) );
		if (a) {
			return a->DoExecAction(transitionToken, c, config);
		} else if (!config.IsNull()) {
			return ExecAction(transitionToken, c, config);
		}
		return true;
	}
	return false;
}

RegCacheImpl(Action);	// FindAction()

//---- PreprocessAction ----------------------------------------------------------------------
class EXPORTDECL_WDBASE PreprocessAction : public Action
{
public:
	PreprocessAction(const char *name);

	virtual bool DoAction(String &action, Context &);
};

RegisterAction(PreprocessAction);
PreprocessAction::PreprocessAction(const char *name)
	: Action(name)
{
}

bool PreprocessAction::DoAction(String &action, Context &c)
{
	StatTrace(PreprocessAction.DoAction, "<" << action << ">", Storage::Current());
	Page *s( c.GetPage() );
	if ( s ) {
		s->Preprocess(c);
	}
	return true;
}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/video_capture/windows/video_capture_ds.h"

#include "webrtc/modules/video_capture/video_capture_config.h"
#include "webrtc/modules/video_capture/windows/help_functions_ds.h"
#include "webrtc/modules/video_capture/windows/sink_filter_ds.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
#include "webrtc/system_wrappers/include/trace.h"

#include <Dvdmedia.h> // VIDEOINFOHEADER2

namespace webrtc
{
namespace videocapturemodule
{
VideoCaptureDS::VideoCaptureDS(const int32_t id)
    : VideoCaptureImpl(id), _dsInfo(id), _captureFilter(NULL),
      _graphBuilder(NULL), _mediaControl(NULL), _sinkFilter(NULL),
      _inputSendPin(NULL), _outputCapturePin(NULL), _dvFilter(NULL),
      _inputDvPin(NULL), _outputDvPin(NULL)
{
}

VideoCaptureDS::~VideoCaptureDS()
{
    if (_mediaControl)
    {
        _mediaControl->Stop();
    }
    if (_graphBuilder)
    {
        if (_sinkFilter)
            _graphBuilder->RemoveFilter(_sinkFilter);
        if (_captureFilter)
            _graphBuilder->RemoveFilter(_captureFilter);
        if (_dvFilter)
            _graphBuilder->RemoveFilter(_dvFilter);
    }
    RELEASE_AND_CLEAR(_inputSendPin);
    RELEASE_AND_CLEAR(_outputCapturePin);

    RELEASE_AND_CLEAR(_captureFilter); // release the capture device
    RELEASE_AND_CLEAR(_sinkFilter);
    RELEASE_AND_CLEAR(_dvFilter);

    RELEASE_AND_CLEAR(_mediaControl);

    RELEASE_AND_CLEAR(_inputDvPin);
    RELEASE_AND_CLEAR(_outputDvPin);

    RELEASE_AND_CLEAR(_graphBuilder);
}

int32_t VideoCaptureDS::Init(const int32_t id, const char* deviceUniqueIdUTF8)
{
    const int32_t nameLength =
        (int32_t) strlen((char*) deviceUniqueIdUTF8);
    if (nameLength > kVideoCaptureUniqueNameLength)
        return -1;

    // Store the device name
    _deviceUniqueId = new (std::nothrow) char[nameLength + 1];
    memcpy(_deviceUniqueId, deviceUniqueIdUTF8, nameLength + 1);

    if (_dsInfo.Init() != 0)
        return -1;

    _captureFilter = _dsInfo.GetDeviceFilter(deviceUniqueIdUTF8);
    if (!_captureFilter)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to create capture filter.");
        return -1;
    }

    // Get the interface for DirectShow's GraphBuilder
    HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL,
                                  CLSCTX_INPROC_SERVER, IID_IGraphBuilder,
                                  (void **) &_graphBuilder);
    if (FAILED(hr))
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to create graph builder.");
        return -1;
    }

    hr = _graphBuilder->QueryInterface(IID_IMediaControl,
                                       (void **) &_mediaControl);
    if (FAILED(hr))
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to create media control builder.");
        return -1;
    }
    hr = _graphBuilder->AddFilter(_captureFilter, CAPTURE_FILTER_NAME);
    if (FAILED(hr))
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to add the capture device to the graph.");
        return -1;
    }

    _outputCapturePin = GetOutputPin(_captureFilter, PIN_CATEGORY_CAPTURE);

    // Create the sink filte used for receiving Captured frames.
    _sinkFilter = new CaptureSinkFilter(SINK_FILTER_NAME, NULL, &hr,
                                        *this, _id);
    if (hr != S_OK)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to create send filter");
        return -1;
    }
    _sinkFilter->AddRef();

    hr = _graphBuilder->AddFilter(_sinkFilter, SINK_FILTER_NAME);
    if (FAILED(hr))
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to add the send filter to the graph.");
        return -1;
    }
    _inputSendPin = GetInputPin(_sinkFilter);

    // Temporary connect here.
    // This is done so that no one else can use the capture device.
    if (SetCameraOutput(_requestedCapability) != 0)
    {
        return -1;
    }
    hr = _mediaControl->Pause();
    if (FAILED(hr))
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to Pause the Capture device. Is it already occupied? %d.",
                     hr);
        return -1;
    }
    WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceVideoCapture, _id,
                 "Capture device '%s' initialized.", deviceUniqueIdUTF8);
    return 0;
}

int32_t VideoCaptureDS::StartCapture(
                                      const VideoCaptureCapability& capability)
{
    CriticalSectionScoped cs(&_apiCs);

    if (capability != _requestedCapability)
    {
        DisconnectGraph();

        if (SetCameraOutput(capability) != 0)
        {
            return -1;
        }
    }
    HRESULT hr = _mediaControl->Run();
    if (FAILED(hr))
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to start the Capture device.");
        return -1;
    }
    return 0;
}

int32_t VideoCaptureDS::StopCapture()
{
    CriticalSectionScoped cs(&_apiCs);

    HRESULT hr = _mediaControl->Pause();
    if (FAILED(hr))
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to stop the capture graph. %d", hr);
        return -1;
    }
    return 0;
}
bool VideoCaptureDS::CaptureStarted()
{
    OAFilterState state = 0;
    HRESULT hr = _mediaControl->GetState(1000, &state);
    if (hr != S_OK && hr != VFW_S_CANT_CUE)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to get the CaptureStarted status");
    }
    WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
                 "CaptureStarted %d", state);
    return state == State_Running;

}
int32_t VideoCaptureDS::CaptureSettings(
                                             VideoCaptureCapability& settings)
{
    settings = _requestedCapability;
    return 0;
}

int32_t VideoCaptureDS::SetCameraOutput(
                             const VideoCaptureCapability& requestedCapability)
{

    // Get the best matching capability
    VideoCaptureCapability capability;
    int32_t capabilityIndex;

    // Store the new requested size
    _requestedCapability = requestedCapability;
    // Match the requested capability with the supported.
    if ((capabilityIndex = _dsInfo.GetBestMatchedCapability(_deviceUniqueId,
                                                            _requestedCapability,
                                                            capability)) < 0)
    {
        return -1;
    }
    //Reduce the frame rate if possible.
    if (capability.maxFPS > requestedCapability.maxFPS)
    {
        capability.maxFPS = requestedCapability.maxFPS;
    } else if (capability.maxFPS <= 0)
    {
        capability.maxFPS = 30;
    }
    // Store the new expected capture delay
    _captureDelay = capability.expectedCaptureDelay;

    // Convert it to the windows capability index since they are not nexessary
    // the same
    VideoCaptureCapabilityWindows windowsCapability;
    if (_dsInfo.GetWindowsCapability(capabilityIndex, windowsCapability) != 0)
    {
        return -1;
    }

    IAMStreamConfig* streamConfig = NULL;
    AM_MEDIA_TYPE *pmt = NULL;
    VIDEO_STREAM_CONFIG_CAPS caps;

    HRESULT hr = _outputCapturePin->QueryInterface(IID_IAMStreamConfig,
                                                   (void**) &streamConfig);
    if (hr)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Can't get the Capture format settings.");
        return -1;
    }

    //Get the windows capability from the capture device
    bool isDVCamera = false;
    hr = streamConfig->GetStreamCaps(
                                    windowsCapability.directShowCapabilityIndex,
                                    &pmt, reinterpret_cast<BYTE*> (&caps));
    if (!FAILED(hr))
    {
        if (pmt->formattype == FORMAT_VideoInfo2)
        {
            VIDEOINFOHEADER2* h =
                reinterpret_cast<VIDEOINFOHEADER2*> (pmt->pbFormat);
            if (capability.maxFPS > 0
                && windowsCapability.supportFrameRateControl)
            {
                h->AvgTimePerFrame = REFERENCE_TIME(10000000.0
                                                    / capability.maxFPS);
            }
        }
        else
        {
            VIDEOINFOHEADER* h = reinterpret_cast<VIDEOINFOHEADER*>
                                (pmt->pbFormat);
            if (capability.maxFPS > 0
                && windowsCapability.supportFrameRateControl)
            {
                h->AvgTimePerFrame = REFERENCE_TIME(10000000.0
                                                    / capability.maxFPS);
            }

        }

        // Set the sink filter to request this capability
        _sinkFilter->SetMatchingMediaType(capability);
        //Order the capture device to use this capability
        hr += streamConfig->SetFormat(pmt);

        //Check if this is a DV camera and we need to add MS DV Filter
        if (pmt->subtype == MEDIASUBTYPE_dvsl
           || pmt->subtype == MEDIASUBTYPE_dvsd
           || pmt->subtype == MEDIASUBTYPE_dvhd)
            isDVCamera = true; // This is a DV camera. Use MS DV filter
    }
    RELEASE_AND_CLEAR(streamConfig);

    if (FAILED(hr))
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to set capture device output format");
        return -1;
    }

    if (isDVCamera)
    {
        hr = ConnectDVCamera();
    }
    else
    {
        hr = _graphBuilder->ConnectDirect(_outputCapturePin, _inputSendPin,
                                          NULL);
    }
    if (hr != S_OK)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to connect the Capture graph %d", hr);
        return -1;
    }
    return 0;
}

int32_t VideoCaptureDS::DisconnectGraph()
{
    HRESULT hr = _mediaControl->Stop();
    hr += _graphBuilder->Disconnect(_outputCapturePin);
    hr += _graphBuilder->Disconnect(_inputSendPin);

    //if the DV camera filter exist
    if (_dvFilter)
    {
        _graphBuilder->Disconnect(_inputDvPin);
        _graphBuilder->Disconnect(_outputDvPin);
    }
    if (hr != S_OK)
    {
        WEBRTC_TRACE( webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to Stop the Capture device for reconfiguration %d",
                     hr);
        return -1;
    }
    return 0;
}
HRESULT VideoCaptureDS::ConnectDVCamera()
{
    HRESULT hr = S_OK;

    if (!_dvFilter)
    {
        hr = CoCreateInstance(CLSID_DVVideoCodec, NULL, CLSCTX_INPROC,
                              IID_IBaseFilter, (void **) &_dvFilter);
        if (hr != S_OK)
        {
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                         "Failed to create the dv decoder: %x", hr);
            return hr;
        }
        hr = _graphBuilder->AddFilter(_dvFilter, L"VideoDecoderDV");
        if (hr != S_OK)
        {
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                         "Failed to add the dv decoder to the graph: %x", hr);
            return hr;
        }
        _inputDvPin = GetInputPin(_dvFilter);
        if (_inputDvPin == NULL)
        {
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                         "Failed to get input pin from DV decoder");
            return -1;
        }
        _outputDvPin = GetOutputPin(_dvFilter, GUID_NULL);
        if (_outputDvPin == NULL)
        {
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                         "Failed to get output pin from DV decoder");
            return -1;
        }
    }
    hr = _graphBuilder->ConnectDirect(_outputCapturePin, _inputDvPin, NULL);
    if (hr != S_OK)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to connect capture device to the dv devoder: %x",
                     hr);
        return hr;
    }

    hr = _graphBuilder->ConnectDirect(_outputDvPin, _inputSendPin, NULL);
    if (hr != S_OK)
    {
        if (hr == (long)0x80070004)
        {
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                         "Failed to connect the capture device, busy");
        }
        else
        {
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                         "Failed to connect capture device to the send graph: 0x%x",
                         hr);
        }
        return hr;
    }
    return hr;
}
}  // namespace videocapturemodule
}  // namespace webrtc
<commit_msg>Replace hardcoded constant in video capture with macro.<commit_after>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/video_capture/windows/video_capture_ds.h"

#include "webrtc/modules/video_capture/video_capture_config.h"
#include "webrtc/modules/video_capture/windows/help_functions_ds.h"
#include "webrtc/modules/video_capture/windows/sink_filter_ds.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
#include "webrtc/system_wrappers/include/trace.h"

#include <Dvdmedia.h> // VIDEOINFOHEADER2

namespace webrtc
{
namespace videocapturemodule
{
VideoCaptureDS::VideoCaptureDS(const int32_t id)
    : VideoCaptureImpl(id), _dsInfo(id), _captureFilter(NULL),
      _graphBuilder(NULL), _mediaControl(NULL), _sinkFilter(NULL),
      _inputSendPin(NULL), _outputCapturePin(NULL), _dvFilter(NULL),
      _inputDvPin(NULL), _outputDvPin(NULL)
{
}

VideoCaptureDS::~VideoCaptureDS()
{
    if (_mediaControl)
    {
        _mediaControl->Stop();
    }
    if (_graphBuilder)
    {
        if (_sinkFilter)
            _graphBuilder->RemoveFilter(_sinkFilter);
        if (_captureFilter)
            _graphBuilder->RemoveFilter(_captureFilter);
        if (_dvFilter)
            _graphBuilder->RemoveFilter(_dvFilter);
    }
    RELEASE_AND_CLEAR(_inputSendPin);
    RELEASE_AND_CLEAR(_outputCapturePin);

    RELEASE_AND_CLEAR(_captureFilter); // release the capture device
    RELEASE_AND_CLEAR(_sinkFilter);
    RELEASE_AND_CLEAR(_dvFilter);

    RELEASE_AND_CLEAR(_mediaControl);

    RELEASE_AND_CLEAR(_inputDvPin);
    RELEASE_AND_CLEAR(_outputDvPin);

    RELEASE_AND_CLEAR(_graphBuilder);
}

int32_t VideoCaptureDS::Init(const int32_t id, const char* deviceUniqueIdUTF8)
{
    const int32_t nameLength =
        (int32_t) strlen((char*) deviceUniqueIdUTF8);
    if (nameLength > kVideoCaptureUniqueNameLength)
        return -1;

    // Store the device name
    _deviceUniqueId = new (std::nothrow) char[nameLength + 1];
    memcpy(_deviceUniqueId, deviceUniqueIdUTF8, nameLength + 1);

    if (_dsInfo.Init() != 0)
        return -1;

    _captureFilter = _dsInfo.GetDeviceFilter(deviceUniqueIdUTF8);
    if (!_captureFilter)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to create capture filter.");
        return -1;
    }

    // Get the interface for DirectShow's GraphBuilder
    HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL,
                                  CLSCTX_INPROC_SERVER, IID_IGraphBuilder,
                                  (void **) &_graphBuilder);
    if (FAILED(hr))
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to create graph builder.");
        return -1;
    }

    hr = _graphBuilder->QueryInterface(IID_IMediaControl,
                                       (void **) &_mediaControl);
    if (FAILED(hr))
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to create media control builder.");
        return -1;
    }
    hr = _graphBuilder->AddFilter(_captureFilter, CAPTURE_FILTER_NAME);
    if (FAILED(hr))
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to add the capture device to the graph.");
        return -1;
    }

    _outputCapturePin = GetOutputPin(_captureFilter, PIN_CATEGORY_CAPTURE);

    // Create the sink filte used for receiving Captured frames.
    _sinkFilter = new CaptureSinkFilter(SINK_FILTER_NAME, NULL, &hr,
                                        *this, _id);
    if (hr != S_OK)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to create send filter");
        return -1;
    }
    _sinkFilter->AddRef();

    hr = _graphBuilder->AddFilter(_sinkFilter, SINK_FILTER_NAME);
    if (FAILED(hr))
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to add the send filter to the graph.");
        return -1;
    }
    _inputSendPin = GetInputPin(_sinkFilter);

    // Temporary connect here.
    // This is done so that no one else can use the capture device.
    if (SetCameraOutput(_requestedCapability) != 0)
    {
        return -1;
    }
    hr = _mediaControl->Pause();
    if (FAILED(hr))
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to Pause the Capture device. Is it already occupied? %d.",
                     hr);
        return -1;
    }
    WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceVideoCapture, _id,
                 "Capture device '%s' initialized.", deviceUniqueIdUTF8);
    return 0;
}

int32_t VideoCaptureDS::StartCapture(
                                      const VideoCaptureCapability& capability)
{
    CriticalSectionScoped cs(&_apiCs);

    if (capability != _requestedCapability)
    {
        DisconnectGraph();

        if (SetCameraOutput(capability) != 0)
        {
            return -1;
        }
    }
    HRESULT hr = _mediaControl->Run();
    if (FAILED(hr))
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to start the Capture device.");
        return -1;
    }
    return 0;
}

int32_t VideoCaptureDS::StopCapture()
{
    CriticalSectionScoped cs(&_apiCs);

    HRESULT hr = _mediaControl->Pause();
    if (FAILED(hr))
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to stop the capture graph. %d", hr);
        return -1;
    }
    return 0;
}
bool VideoCaptureDS::CaptureStarted()
{
    OAFilterState state = 0;
    HRESULT hr = _mediaControl->GetState(1000, &state);
    if (hr != S_OK && hr != VFW_S_CANT_CUE)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to get the CaptureStarted status");
    }
    WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
                 "CaptureStarted %d", state);
    return state == State_Running;

}
int32_t VideoCaptureDS::CaptureSettings(
                                             VideoCaptureCapability& settings)
{
    settings = _requestedCapability;
    return 0;
}

int32_t VideoCaptureDS::SetCameraOutput(
                             const VideoCaptureCapability& requestedCapability)
{

    // Get the best matching capability
    VideoCaptureCapability capability;
    int32_t capabilityIndex;

    // Store the new requested size
    _requestedCapability = requestedCapability;
    // Match the requested capability with the supported.
    if ((capabilityIndex = _dsInfo.GetBestMatchedCapability(_deviceUniqueId,
                                                            _requestedCapability,
                                                            capability)) < 0)
    {
        return -1;
    }
    //Reduce the frame rate if possible.
    if (capability.maxFPS > requestedCapability.maxFPS)
    {
        capability.maxFPS = requestedCapability.maxFPS;
    } else if (capability.maxFPS <= 0)
    {
        capability.maxFPS = 30;
    }
    // Store the new expected capture delay
    _captureDelay = capability.expectedCaptureDelay;

    // Convert it to the windows capability index since they are not nexessary
    // the same
    VideoCaptureCapabilityWindows windowsCapability;
    if (_dsInfo.GetWindowsCapability(capabilityIndex, windowsCapability) != 0)
    {
        return -1;
    }

    IAMStreamConfig* streamConfig = NULL;
    AM_MEDIA_TYPE *pmt = NULL;
    VIDEO_STREAM_CONFIG_CAPS caps;

    HRESULT hr = _outputCapturePin->QueryInterface(IID_IAMStreamConfig,
                                                   (void**) &streamConfig);
    if (hr)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Can't get the Capture format settings.");
        return -1;
    }

    //Get the windows capability from the capture device
    bool isDVCamera = false;
    hr = streamConfig->GetStreamCaps(
                                    windowsCapability.directShowCapabilityIndex,
                                    &pmt, reinterpret_cast<BYTE*> (&caps));
    if (!FAILED(hr))
    {
        if (pmt->formattype == FORMAT_VideoInfo2)
        {
            VIDEOINFOHEADER2* h =
                reinterpret_cast<VIDEOINFOHEADER2*> (pmt->pbFormat);
            if (capability.maxFPS > 0
                && windowsCapability.supportFrameRateControl)
            {
                h->AvgTimePerFrame = REFERENCE_TIME(10000000.0
                                                    / capability.maxFPS);
            }
        }
        else
        {
            VIDEOINFOHEADER* h = reinterpret_cast<VIDEOINFOHEADER*>
                                (pmt->pbFormat);
            if (capability.maxFPS > 0
                && windowsCapability.supportFrameRateControl)
            {
                h->AvgTimePerFrame = REFERENCE_TIME(10000000.0
                                                    / capability.maxFPS);
            }

        }

        // Set the sink filter to request this capability
        _sinkFilter->SetMatchingMediaType(capability);
        //Order the capture device to use this capability
        hr += streamConfig->SetFormat(pmt);

        //Check if this is a DV camera and we need to add MS DV Filter
        if (pmt->subtype == MEDIASUBTYPE_dvsl
           || pmt->subtype == MEDIASUBTYPE_dvsd
           || pmt->subtype == MEDIASUBTYPE_dvhd)
            isDVCamera = true; // This is a DV camera. Use MS DV filter
    }
    RELEASE_AND_CLEAR(streamConfig);

    if (FAILED(hr))
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to set capture device output format");
        return -1;
    }

    if (isDVCamera)
    {
        hr = ConnectDVCamera();
    }
    else
    {
        hr = _graphBuilder->ConnectDirect(_outputCapturePin, _inputSendPin,
                                          NULL);
    }
    if (hr != S_OK)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to connect the Capture graph %d", hr);
        return -1;
    }
    return 0;
}

int32_t VideoCaptureDS::DisconnectGraph()
{
    HRESULT hr = _mediaControl->Stop();
    hr += _graphBuilder->Disconnect(_outputCapturePin);
    hr += _graphBuilder->Disconnect(_inputSendPin);

    //if the DV camera filter exist
    if (_dvFilter)
    {
        _graphBuilder->Disconnect(_inputDvPin);
        _graphBuilder->Disconnect(_outputDvPin);
    }
    if (hr != S_OK)
    {
        WEBRTC_TRACE( webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to Stop the Capture device for reconfiguration %d",
                     hr);
        return -1;
    }
    return 0;
}
HRESULT VideoCaptureDS::ConnectDVCamera()
{
    HRESULT hr = S_OK;

    if (!_dvFilter)
    {
        hr = CoCreateInstance(CLSID_DVVideoCodec, NULL, CLSCTX_INPROC,
                              IID_IBaseFilter, (void **) &_dvFilter);
        if (hr != S_OK)
        {
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                         "Failed to create the dv decoder: %x", hr);
            return hr;
        }
        hr = _graphBuilder->AddFilter(_dvFilter, L"VideoDecoderDV");
        if (hr != S_OK)
        {
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                         "Failed to add the dv decoder to the graph: %x", hr);
            return hr;
        }
        _inputDvPin = GetInputPin(_dvFilter);
        if (_inputDvPin == NULL)
        {
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                         "Failed to get input pin from DV decoder");
            return -1;
        }
        _outputDvPin = GetOutputPin(_dvFilter, GUID_NULL);
        if (_outputDvPin == NULL)
        {
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                         "Failed to get output pin from DV decoder");
            return -1;
        }
    }
    hr = _graphBuilder->ConnectDirect(_outputCapturePin, _inputDvPin, NULL);
    if (hr != S_OK)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                     "Failed to connect capture device to the dv devoder: %x",
                     hr);
        return hr;
    }

    hr = _graphBuilder->ConnectDirect(_outputDvPin, _inputSendPin, NULL);
    if (hr != S_OK)
    {
        if (hr == HRESULT_FROM_WIN32(ERROR_TOO_MANY_OPEN_FILES))
        {
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                         "Failed to connect the capture device, busy");
        }
        else
        {
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
                         "Failed to connect capture device to the send graph: 0x%x",
                         hr);
        }
        return hr;
    }
    return hr;
}
}  // namespace videocapturemodule
}  // namespace webrtc
<|endoftext|>