<commit_before>AliAnalysisTaskEmcalDiJetResponse* AddTaskEmcalDiJetResponse(TString     kTracksName         = "PicoTracks",
							     TString     kClusName           = "caloClusterCorr",
							     TString     kMCTracksName       = "MCParticles",
							     Double_t    R                   = 0.4,
							     Double_t    ptminTrack          = 0.15,
							     Double_t    etminClus           = 0.3,
							     Int_t       rhoType             = 0,
							     TString     trigClass           = "",
							     const char *CentEst             = "V0A",
							     Int_t       pSel                = AliVEvent::kINT7,
							     Int_t       matchFullCh         = AliAnalysisTaskEmcalDiJetBase::kNoMatching,
							     Double_t    ptTrackBias         = 0.,
							     Int_t       responseVar         = 0,
							     Int_t       corrType            = AliAnalysisTaskEmcalDiJetBase::kCorrelateTwo,
							     Float_t     nefCut              = 0.95
							     ) {

  enum AlgoType {kKT, kANTIKT};
  enum JetType  {kFULLJETS, kCHARGEDJETS, kNEUTRALJETS};

  // #### Define manager and data container names
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    ::Error("AddTaskEmcalDiJet", "No analysis manager to connect to.");
    return NULL;
  }

  // Check the analysis type using the event handlers connected to the analysis manager.
  //==============================================================================
  if (!mgr->GetInputEventHandler())
    {
      ::Error("AddTaskEmcalDiJet", "This task requires an input event handler");
      return NULL;
    }

  // #### Add necessary jet finder tasks
  gROOT->LoadMacro("$ALICE_ROOT/PWGJE/EMCALJetTasks/macros/AddTaskEmcalJet.C");

  AliEmcalJetTask* jetFinderTaskFull    = AddTaskEmcalJet(kTracksName, kClusName, kANTIKT, R, kFULLJETS, ptminTrack, etminClus);
  AliEmcalJetTask* jetFinderTaskCharged = AddTaskEmcalJet(kTracksName, kClusName, kANTIKT, R, kCHARGEDJETS, ptminTrack, etminClus);

  AliEmcalJetTask* jetFinderTaskFullMC = AddTaskEmcalJet(kMCTracksName ,"", kANTIKT, R, kFULLJETS, kPartLevPtCut, kPartLevPtCut);
  AliEmcalJetTask* jetFinderTaskChargedMC = AddTaskEmcalJet(kMCTracksName ,"", kANTIKT, R, kCHARGEDJETS, kPartLevPtCut, kPartLevPtCut);

  TString strJetsFull = jetFinderTaskFull->GetName();
  TString strJetsCh   = jetFinderTaskCharged->GetName();

  TString strJetsFullMC = jetFinderTaskFullMC->GetName();
  TString strJetsChMC   = jetFinderTaskChargedMC->GetName();

  TString wagonName = Form("DiJetResponse_%s_%s_Rho%dTC%sMatch%dHadTrig%dRV%d",strJetsFull.Data(),strJetsFullMC.Data(),rhoType,trigClass.Data(),matchFullCh,(Int_t)(ptTrackBias),responseVar);

  //Configure DiJet task
  AliAnalysisTaskEmcalDiJetResponse *taskDiJet = new AliAnalysisTaskEmcalDiJetResponse(wagonName.Data());

  Printf("strJetsFull: %s",strJetsFull.Data());
  Printf("strJetsCh: %s",strJetsCh.Data());

  taskDiJet->SetUseAliAnaUtils(kTRUE);
  taskDiJet->SetIsPythia(kTRUE);

  taskDiJet->SetJetCorrelationType(corrType);

  taskDiJet->SetContainerFull(0);
  taskDiJet->SetContainerCharged(1);
  taskDiJet->SetContainerFullMC(2);
  taskDiJet->SetContainerChargedMC(3);

  taskDiJet->AddParticleContainer(kTracksName.Data());
  taskDiJet->AddClusterContainer(kClusName.Data());

  taskDiJet->AddJetContainer(strJetsFull.Data(),"EMCAL",R);
  taskDiJet->AddJetContainer(strJetsCh.Data(),"TPC",R);
  taskDiJet->AddJetContainer(strJetsFullMC.Data(),"EMCAL",R);
  taskDiJet->AddJetContainer(strJetsChMC.Data(),"TPC",R);

  taskDiJet->SetZLeadingCut(0.98,0.98,0);
  taskDiJet->SetZLeadingCut(0.98,0.98,2);

  taskDiJet->SetNEFCut(0.,nefCut,0);
  taskDiJet->SetNEFCut(0.,nefCut,2);

  for(Int_t i=0; i<4; i++) {
    taskDiJet->SetPercAreaCut(0.6, i);
    taskDiJet->SetPtBiasJetTrack(ptTrackBias,i);
  }

  taskDiJet->SetRhoType(rhoType);

  taskDiJet->SetCentralityEstimator(CentEst);

  taskDiJet->SelectCollisionCandidates(pSel);

  taskDiJet->SetFullChargedMatchingType(matchFullCh);

  taskDiJet->SetDoChargedCharged(kTRUE);
  taskDiJet->SetDoFullCharged(kTRUE);
  taskDiJet->SetMatchFullCharged(kTRUE);

  taskDiJet->SetResponseVar(responseVar);

  mgr->AddTask(taskDiJet);

  //Connnect input
  mgr->ConnectInput (taskDiJet, 0, mgr->GetCommonInputContainer() );

  //Connect output
  AliAnalysisDataContainer *coutput1 = 0x0;

  TString contName(wagonName);
  contName += "_histos";

  //  TString outputfile = Form("%s:%s",AliAnalysisManager::GetCommonFileName(),wagonName.Data());
  TString outputfile = Form("%s",AliAnalysisManager::GetCommonFileName());

  coutput1 = mgr->CreateContainer(contName.Data(), TList::Class(),AliAnalysisManager::kOutputContainer,outputfile);

  mgr->ConnectOutput(taskDiJet,1,coutput1);

  return taskDiJet;
}
<commit_msg>change default setting<commit_after>AliAnalysisTaskEmcalDiJetResponse* AddTaskEmcalDiJetResponse(TString     kTracksName         = "PicoTracks",
							     TString     kClusName           = "caloClusterCorr",
							     TString     kMCTracksName       = "MCParticles",
							     Double_t    R                   = 0.4,
							     Double_t    ptminTrack          = 0.15,
							     Double_t    etminClus           = 0.3,
							     Int_t       rhoType             = 0,
							     TString     trigClass           = "",
							     const char *CentEst             = "V0A",
							     Int_t       pSel                = AliVEvent::kINT7,
							     Int_t       matchFullCh         = AliAnalysisTaskEmcalDiJetBase::kNoMatching,
							     Double_t    ptTrackBias         = 0.,
							     Int_t       responseVar         = 0,
							     Int_t       corrType            = AliAnalysisTaskEmcalDiJetBase::kCorrelateTwo,
							     Float_t     nefCut              = 0.95
							     ) {

  enum AlgoType {kKT, kANTIKT};
  enum JetType  {kFULLJETS, kCHARGEDJETS, kNEUTRALJETS};

  // #### Define manager and data container names
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    ::Error("AddTaskEmcalDiJet", "No analysis manager to connect to.");
    return NULL;
  }

  // Check the analysis type using the event handlers connected to the analysis manager.
  //==============================================================================
  if (!mgr->GetInputEventHandler())
    {
      ::Error("AddTaskEmcalDiJet", "This task requires an input event handler");
      return NULL;
    }

  // #### Add necessary jet finder tasks
  gROOT->LoadMacro("$ALICE_ROOT/PWGJE/EMCALJetTasks/macros/AddTaskEmcalJet.C");

  AliEmcalJetTask* jetFinderTaskFull    = AddTaskEmcalJet(kTracksName, kClusName, kANTIKT, R, kFULLJETS, ptminTrack, etminClus);
  AliEmcalJetTask* jetFinderTaskCharged = AddTaskEmcalJet(kTracksName, kClusName, kANTIKT, R, kCHARGEDJETS, ptminTrack, etminClus);

  AliEmcalJetTask* jetFinderTaskFullMC = AddTaskEmcalJet(kMCTracksName ,"", kANTIKT, R, kFULLJETS, kPartLevPtCut, kPartLevPtCut);
  AliEmcalJetTask* jetFinderTaskChargedMC = AddTaskEmcalJet(kMCTracksName ,"", kANTIKT, R, kCHARGEDJETS, kPartLevPtCut, kPartLevPtCut);

  TString strJetsFull = jetFinderTaskFull->GetName();
  TString strJetsCh   = jetFinderTaskCharged->GetName();

  TString strJetsFullMC = jetFinderTaskFullMC->GetName();
  TString strJetsChMC   = jetFinderTaskChargedMC->GetName();

  TString wagonName = Form("DiJetResponse_%s_%s_Rho%dTC%sMatch%dHadTrig%dRV%d",strJetsFull.Data(),strJetsFullMC.Data(),rhoType,trigClass.Data(),matchFullCh,(Int_t)(ptTrackBias),responseVar);

  //Configure DiJet task
  AliAnalysisTaskEmcalDiJetResponse *taskDiJet = new AliAnalysisTaskEmcalDiJetResponse(wagonName.Data());

  Printf("strJetsFull: %s",strJetsFull.Data());
  Printf("strJetsCh: %s",strJetsCh.Data());

  taskDiJet->SetUseAliAnaUtils(kTRUE);
  taskDiJet->SetIsPythia(kTRUE);

  taskDiJet->SetJetCorrelationType(corrType);

  taskDiJet->SetContainerFull(0);
  taskDiJet->SetContainerCharged(1);
  taskDiJet->SetContainerFullMC(2);
  taskDiJet->SetContainerChargedMC(3);

  taskDiJet->AddParticleContainer(kTracksName.Data());
  taskDiJet->AddClusterContainer(kClusName.Data());

  taskDiJet->AddJetContainer(strJetsFull.Data(),"EMCAL",R);
  taskDiJet->AddJetContainer(strJetsCh.Data(),"TPC",R);
  taskDiJet->AddJetContainer(strJetsFullMC.Data(),"EMCAL",R);
  taskDiJet->AddJetContainer(strJetsChMC.Data(),"TPC",R);

  taskDiJet->SetZLeadingCut(0.98,0.98,0);
  taskDiJet->SetZLeadingCut(0.98,0.98,2);

  taskDiJet->SetNEFCut(0.,nefCut,0);
  taskDiJet->SetNEFCut(0.,nefCut,2);

  for(Int_t i=0; i<4; i++) {
    taskDiJet->SetPercAreaCut(0.6, i);
    taskDiJet->SetPtBiasJetTrack(ptTrackBias,i);
  }

  taskDiJet->SetRhoType(rhoType);

  taskDiJet->SetCentralityEstimator(CentEst);

  taskDiJet->SelectCollisionCandidates(pSel);

  taskDiJet->SetFullChargedMatchingType(matchFullCh);

  taskDiJet->SetDoChargedCharged(kTRUE);
  taskDiJet->SetDoFullCharged(kTRUE);
  taskDiJet->SetMatchFullCharged(kTRUE);

  taskDiJet->SetResponseVar(responseVar);

  taskDiJet->SetPtMinTriggerJet(0.);

  mgr->AddTask(taskDiJet);

  //Connnect input
  mgr->ConnectInput (taskDiJet, 0, mgr->GetCommonInputContainer() );

  //Connect output
  AliAnalysisDataContainer *coutput1 = 0x0;

  TString contName(wagonName);
  contName += "_histos";

  //  TString outputfile = Form("%s:%s",AliAnalysisManager::GetCommonFileName(),wagonName.Data());
  TString outputfile = Form("%s",AliAnalysisManager::GetCommonFileName());

  coutput1 = mgr->CreateContainer(contName.Data(), TList::Class(),AliAnalysisManager::kOutputContainer,outputfile);

  mgr->ConnectOutput(taskDiJet,1,coutput1);

  return taskDiJet;
}
<|endoftext|>


<commit_before>#include "single_producer_sequencer.h"
#include "multi_producer_sequencer.h"
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <functional>
#include <thread>
#include <condition_variable>
#include "blocking_wait_strategy.h"
#include "sequence.h"

using namespace magic_bean;

enum ProducerType {
  SINGLE,
  MULTI
};

class SequencerTest : public ::testing::TestWithParam<int> {
 public:
  void Execute() {
    waiting_cond.notify_all();
    int64_t next = sequencer->Next();
    sequencer->Publish(next);
    done_cond.notify_all();
  }
 protected:
  SequencerTest() {
    producer_type = GetParam();
  }
  virtual ~SequencerTest() {};

  virtual void SetUp() {
    wait_strategy = new BlockingWaitStrategy();
    sequencer = NewProducer(producer_type, wait_strategy);
    gating_sequence = SequencePtr(new Sequence());
  }
  virtual void TearDown() {
    gating_sequence.reset();
    delete sequencer;
    delete wait_strategy;
  }

 private:
  Sequencer* NewProducer(int producer_type, WaitStrategy* strategy) {
    if(producer_type == ProducerType::SINGLE)
      return new SingleProducerSequencer(BUFFER_SIZE, strategy);
    else if(producer_type == ProducerType::MULTI)
      return new MultiProducerSequencer(BUFFER_SIZE, strategy);
    return nullptr;
  }
 protected:
  int producer_type;
  Sequencer* sequencer;
  WaitStrategy* wait_strategy;
  SequencePtr gating_sequence;
  static const int BUFFER_SIZE = 16;
  static const int64_t INITIAL_CURSOR_VALUE = -1;
  std::condition_variable waiting_cond;
  std::mutex waiting_mutex;
  std::condition_variable done_cond;
  std::mutex done_mutex;
};

TEST_P(SequencerTest, should_start_with_initial_value) {
  ASSERT_EQ(0, sequencer->Next());
}

TEST_P(SequencerTest, should_batch_claim) {
  ASSERT_EQ(3, sequencer->Next(4));
}

TEST_P(SequencerTest, should_indicate_has_available_capacity) {
  std::vector<SequencePtr> gating_sequences;
  gating_sequences.push_back(gating_sequence);
  sequencer->AddGatingSequences(gating_sequences);

  ASSERT_TRUE(sequencer->HasAvailableCapacity(1));
  ASSERT_TRUE(sequencer->HasAvailableCapacity(BUFFER_SIZE));
  ASSERT_FALSE(sequencer->HasAvailableCapacity(BUFFER_SIZE + 1));

  sequencer->Publish(sequencer->Next());
  ASSERT_TRUE(sequencer->HasAvailableCapacity(BUFFER_SIZE - 1));
  ASSERT_FALSE(sequencer->HasAvailableCapacity(BUFFER_SIZE));
}

TEST_P(SequencerTest, should_indicate_no_available_capacity) {
  std::vector<SequencePtr> gating_sequences;
  gating_sequences.push_back(gating_sequence);
  sequencer->AddGatingSequences(gating_sequences);

  int64_t sequence = sequencer->Next(16);
  sequencer->Publish(sequence - (BUFFER_SIZE - 1), sequence);
  ASSERT_FALSE(sequencer->HasAvailableCapacity(1));
}

TEST_P(SequencerTest, should_holdup_publisher_when_buffer_is_full) {
  std::vector<SequencePtr> gating_sequences;
  gating_sequences.push_back(gating_sequence);
  sequencer->AddGatingSequences(gating_sequences);

  int64_t sequence = sequencer->Next(BUFFER_SIZE);
  sequencer->Publish(sequence - (BUFFER_SIZE - 1), sequence);

  std::unique_lock<std::mutex> done_lock(done_mutex);
  std::unique_lock<std::mutex> waiting_lock(waiting_mutex);

  int64_t expected_full_sequence = INITIAL_CURSOR_VALUE + sequencer->GetBufferSize();
  ASSERT_EQ(sequencer->GetCursor(), expected_full_sequence);

  std::thread thread(std::bind(&SequencerTest::Execute, this));

  waiting_cond.wait(waiting_lock);
  ASSERT_EQ(sequencer->GetCursor(), expected_full_sequence);
  gating_sequence->Set(INITIAL_CURSOR_VALUE + 1);
  done_cond.wait(done_lock);

  ASSERT_EQ(sequencer->GetCursor(), expected_full_sequence + 1);
}

INSTANTIATE_TEST_CASE_P(AllProducerSequencerTest, SequencerTest, ::testing::Range(0, 2));
<commit_msg>fix test sequencer case bug.<commit_after>#include "single_producer_sequencer.h"
#include "multi_producer_sequencer.h"
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <functional>
#include <thread>
#include <condition_variable>
#include "blocking_wait_strategy.h"
#include "sequence.h"

using namespace magic_bean;

enum ProducerType {
  SINGLE,
  MULTI
};

class SequencerTest : public ::testing::TestWithParam<int> {
 public:
  void Execute() {
    waiting_cond.notify_all();
    int64_t next = sequencer->Next();
    sequencer->Publish(next);
    done_cond.notify_all();
  }
 protected:
  SequencerTest() {
    producer_type = GetParam();
  }
  virtual ~SequencerTest() {};

  virtual void SetUp() {
    wait_strategy = new BlockingWaitStrategy();
    sequencer = NewProducer(producer_type, wait_strategy);
    gating_sequence = SequencePtr(new Sequence());
  }
  virtual void TearDown() {
    gating_sequence.reset();
    delete sequencer;
    delete wait_strategy;
  }

 private:
  Sequencer* NewProducer(int producer_type, WaitStrategy* strategy) {
    if(producer_type == ProducerType::SINGLE)
      return new SingleProducerSequencer(BUFFER_SIZE, strategy);
    else if(producer_type == ProducerType::MULTI)
      return new MultiProducerSequencer(BUFFER_SIZE, strategy);
    return nullptr;
  }
 protected:
  int producer_type;
  Sequencer* sequencer;
  WaitStrategy* wait_strategy;
  SequencePtr gating_sequence;
  static const int BUFFER_SIZE = 16;
  static const int64_t INITIAL_CURSOR_VALUE = -1;
  std::condition_variable waiting_cond;
  std::mutex waiting_mutex;
  std::condition_variable done_cond;
  std::mutex done_mutex;
};

TEST_P(SequencerTest, should_start_with_initial_value) {
  ASSERT_EQ(0, sequencer->Next());
}

TEST_P(SequencerTest, should_batch_claim) {
  ASSERT_EQ(3, sequencer->Next(4));
}

TEST_P(SequencerTest, should_indicate_has_available_capacity) {
  std::vector<SequencePtr> gating_sequences;
  gating_sequences.push_back(gating_sequence);
  sequencer->AddGatingSequences(gating_sequences);

  ASSERT_TRUE(sequencer->HasAvailableCapacity(1));
  ASSERT_TRUE(sequencer->HasAvailableCapacity(BUFFER_SIZE));
  ASSERT_FALSE(sequencer->HasAvailableCapacity(BUFFER_SIZE + 1));

  sequencer->Publish(sequencer->Next());
  ASSERT_TRUE(sequencer->HasAvailableCapacity(BUFFER_SIZE - 1));
  ASSERT_FALSE(sequencer->HasAvailableCapacity(BUFFER_SIZE));
}

TEST_P(SequencerTest, should_indicate_no_available_capacity) {
  std::vector<SequencePtr> gating_sequences;
  gating_sequences.push_back(gating_sequence);
  sequencer->AddGatingSequences(gating_sequences);

  int64_t sequence = sequencer->Next(16);
  sequencer->Publish(sequence - (BUFFER_SIZE - 1), sequence);
  ASSERT_FALSE(sequencer->HasAvailableCapacity(1));
}

TEST_P(SequencerTest, should_holdup_publisher_when_buffer_is_full) {
  std::vector<SequencePtr> gating_sequences;
  gating_sequences.push_back(gating_sequence);
  sequencer->AddGatingSequences(gating_sequences);

  int64_t sequence = sequencer->Next(BUFFER_SIZE);
  sequencer->Publish(sequence - (BUFFER_SIZE - 1), sequence);

  std::unique_lock<std::mutex> done_lock(done_mutex);
  std::unique_lock<std::mutex> waiting_lock(waiting_mutex);

  int64_t expected_full_sequence = INITIAL_CURSOR_VALUE + sequencer->GetBufferSize();
  ASSERT_EQ(sequencer->GetCursor(), expected_full_sequence);

  std::thread thread(std::bind(&SequencerTest::Execute, this));

  waiting_cond.wait(waiting_lock);
  ASSERT_EQ(sequencer->GetCursor(), expected_full_sequence);
  gating_sequence->Set(INITIAL_CURSOR_VALUE + 1);
  done_cond.wait(done_lock);

  ASSERT_EQ(sequencer->GetCursor(), expected_full_sequence + 1);
  thread.join();
}

INSTANTIATE_TEST_CASE_P(AllProducerSequencerTest, SequencerTest, ::testing::Range(0, 2));
<|endoftext|>


<commit_before>/*
  The MIT License (MIT)

  Copyright (c) 2015-2021 Andrea Scarpino <andrea@scarpino.dev>

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.
*/

#include <QApplication>
#include <QtQuick>

#include <sailfishapp.h>

#include "lyricsmanager.h"

int main(int argc, char *argv[])
{
    //QScopedPointer<QGuiApplication> app(SailfishApp::application(argc, argv));
    // Needed by QWebPage
    QScopedPointer<QApplication> app(new QApplication(argc, argv));
    QScopedPointer<QQuickView> view(SailfishApp::createView());

    QCoreApplication::setApplicationName(QStringLiteral("harbour-lyrics"));
    QCoreApplication::setOrganizationDomain(QStringLiteral("andreascarpino.it"));

    LyricsManager manager;
    view->rootContext()->setContextProperty("manager", &manager);

    view->setSource(SailfishApp::pathTo("qml/Lyrics.qml"));
    view->show();

    return app->exec();
}
<commit_msg>Load translations<commit_after>/*
  The MIT License (MIT)

  Copyright (c) 2015-2021 Andrea Scarpino <andrea@scarpino.dev>

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.
*/

#include <QApplication>
#include <QtQuick>

#include <sailfishapp.h>

#include "lyricsmanager.h"

int main(int argc, char *argv[])
{
    //QScopedPointer<QGuiApplication> app(SailfishApp::application(argc, argv));
    // Needed by QWebPage
    QScopedPointer<QApplication> app(new QApplication(argc, argv));
    QScopedPointer<QQuickView> view(SailfishApp::createView());

    QTranslator translator;
    translator.load(QLocale::system(), "harbour-lyrics", "-", SailfishApp::pathTo("translations").toLocalFile());
    app->installTranslator(&translator);

    QCoreApplication::setApplicationName(QStringLiteral("harbour-lyrics"));
    QCoreApplication::setOrganizationDomain(QStringLiteral("andreascarpino.it"));

    LyricsManager manager;
    view->rootContext()->setContextProperty("manager", &manager);

    view->setSource(SailfishApp::pathTo("qml/Lyrics.qml"));
    view->show();

    return app->exec();
}
<|endoftext|>


<commit_before>/*

This file is part of VROOM.

Copyright (c) 2015-2021, Julien Coupey.
All rights reserved (see LICENSE).

*/

#include <fstream>
#include <iostream>
#include <sstream>
#ifndef _WIN32
#include <unistd.h>
#else
#include "getopt_win.h"
#endif

#if USE_LIBOSRM
#include "osrm/exception.hpp"
#endif

#include "problems/vrp.h"
#include "structures/cl_args.h"
#include "utils/helpers.h"
#include "utils/input_parser.h"
#include "utils/output_json.h"
#include "utils/version.h"

void display_usage() {
  std::string usage = "VROOM Copyright (C) 2015-2021, Julien Coupey\n";
  usage += "Version: " + vroom::get_version() + "\n";
  usage += "Usage:\n\tvroom [OPTION]... \"INPUT\"";
  usage += "\n\tvroom [OPTION]... -i FILE\n";
  usage += "\tvroom [OPTION]...\n";
  usage += "Options:\n";
  usage += "\t-a PROFILE:HOST (=" + vroom::DEFAULT_PROFILE +
           ":0.0.0.0)\t routing server\n";
  usage += "\t-c,\t\t\t\t choose ETA for custom routes and report violations\n";
  usage += "\t-g,\t\t\t\t add detailed route geometry and indicators\n";
  usage += "\t-i FILE,\t\t\t read input from FILE rather than from stdin\n";
  usage += "\t-l LIMIT,\t\t\t stop solving process after LIMIT seconds\n";
  usage += "\t-o OUTPUT,\t\t\t output file name\n";
  usage += "\t-p PROFILE:PORT (=" + vroom::DEFAULT_PROFILE +
           ":5000),\t routing server port\n";
  usage += "\t-r ROUTER (=osrm),\t\t osrm, libosrm, ors or valhalla\n";
  usage += "\t-t THREADS (=4),\t\t number of threads to use\n";
  usage += "\t-x EXPLORE (=5),\t\t exploration level to use (0..5)";
  std::cout << usage << std::endl;
  exit(0);
}

int main(int argc, char** argv) {
  // Load default command-line options.
  vroom::io::CLArgs cl_args;

  // Parsing command-line arguments.
  const char* optString = "a:ce:gi:l:o:p:r:t:x:h?";
  int opt = getopt(argc, argv, optString);

  std::string router_arg;
  std::string limit_arg = "";
  std::string nb_threads_arg = std::to_string(cl_args.nb_threads);
  std::string exploration_level_arg = std::to_string(cl_args.exploration_level);
  std::vector<std::string> heuristic_params_arg;

  while (opt != -1) {
    switch (opt) {
    case 'a':
      vroom::io::update_host(cl_args.servers, optarg);
      break;
    case 'c':
      cl_args.check = true;
      break;
    case 'e':
      heuristic_params_arg.push_back(optarg);
      break;
    case 'g':
      cl_args.geometry = true;
      break;
    case 'h':
      display_usage();
      break;
    case 'i':
      cl_args.input_file = optarg;
      break;
    case 'l':
      limit_arg = optarg;
      break;
    case 'o':
      cl_args.output_file = optarg;
      break;
    case 'p':
      vroom::io::update_port(cl_args.servers, optarg);
      break;
    case 'r':
      router_arg = optarg;
      break;
    case 't':
      nb_threads_arg = optarg;
      break;
    case 'x':
      exploration_level_arg = optarg;
      break;
    default:
      break;
    }
    opt = getopt(argc, argv, optString);
  }

  try {
    // Needs to be done after previous switch to make sure the
    // appropriate output file is set.
    if (!limit_arg.empty()) {
      // Internally timeout is in milliseconds.
      cl_args.timeout = 1000 * std::stof(limit_arg);
    }
    cl_args.nb_threads = std::stoul(nb_threads_arg);
    cl_args.exploration_level = std::stoul(exploration_level_arg);

    cl_args.exploration_level =
      std::min(cl_args.exploration_level, cl_args.max_exploration_level);
  } catch (const std::exception& e) {
    auto error_code = vroom::InputException("").error_code;
    std::string message = "Invalid numerical value in option.";
    std::cerr << "[Error] " << message << std::endl;
    vroom::io::write_to_json({error_code, message}, false, cl_args.output_file);
    exit(error_code);
  }

  // Determine routing engine (defaults to ROUTER::OSRM).
  if (router_arg == "libosrm") {
    cl_args.router = vroom::ROUTER::LIBOSRM;
  } else if (router_arg == "ors") {
    cl_args.router = vroom::ROUTER::ORS;
  } else if (router_arg == "valhalla") {
    cl_args.router = vroom::ROUTER::VALHALLA;
  } else if (!router_arg.empty() and router_arg != "osrm") {
    auto error_code = vroom::InputException("").error_code;
    std::string message = "Invalid routing engine: " + router_arg + ".";
    std::cerr << "[Error] " << message << std::endl;
    vroom::io::write_to_json({error_code, message}, false, cl_args.output_file);
    exit(error_code);
  }

  try {
    // Force heuristic parameters from the command-line, useful for
    // debugging.
    std::transform(heuristic_params_arg.begin(),
                   heuristic_params_arg.end(),
                   std::back_inserter(cl_args.h_params),
                   [](const auto& str_param) {
                     return vroom::utils::str_to_heuristic_param(str_param);
                   });
  } catch (const vroom::Exception& e) {
    std::cerr << "[Error] " << e.message << std::endl;
    vroom::io::write_to_json({e.error_code, e.message},
                             false,
                             cl_args.output_file);
    exit(e.error_code);
  }

  // Add default server if none provided in input.
  if (cl_args.servers.empty()) {
    cl_args.servers.emplace(vroom::DEFAULT_PROFILE, vroom::Server());
  }

  // Read input problem
  if (optind == argc) {
    std::stringstream buffer;
    if (cl_args.input_file.empty()) {
      // Getting input from stdin.
      buffer << std::cin.rdbuf();
    } else {
      // Getting input from provided file.
      std::ifstream ifs(cl_args.input_file);
      buffer << ifs.rdbuf();
    }
    cl_args.input = buffer.str();
  } else {
    // Getting input from command-line.
    cl_args.input = argv[optind];
  }

  try {
    // Build problem.
    vroom::Input problem_instance = vroom::io::parse(cl_args);

    vroom::Solution sol = (cl_args.check)
                            ? problem_instance.check(cl_args.nb_threads)
                            : problem_instance.solve(cl_args.exploration_level,
                                                     cl_args.nb_threads,
                                                     cl_args.timeout,
                                                     cl_args.h_params);

    // Write solution.
    vroom::io::write_to_json(sol, cl_args.geometry, cl_args.output_file);
  } catch (const vroom::Exception& e) {
    std::cerr << "[Error] " << e.message << std::endl;
    vroom::io::write_to_json({e.error_code, e.message},
                             false,
                             cl_args.output_file);
    exit(e.error_code);
  }
#if USE_LIBOSRM
  catch (const osrm::exception& e) {
    // In case of an unhandled routing error.
    auto error_code = vroom::RouterException("").error_code;
    auto message = "Routing problem: " + std::string(e.what());
    std::cerr << "[Error] " << message << std::endl;
    vroom::io::write_to_json({error_code, message}, false, cl_args.output_file);
    exit(error_code);
  }
#endif
  catch (const std::exception& e) {
    // In case of an unhandled internal error.
    auto error_code = vroom::InternalException("").error_code;
    std::cerr << "[Error] " << e.what() << std::endl;
    vroom::io::write_to_json({error_code, e.what()},
                             false,
                             cl_args.output_file);
    exit(error_code);
  }

  return 0;
}
<commit_msg>adding missing include under libosrm<commit_after>/*

This file is part of VROOM.

Copyright (c) 2015-2021, Julien Coupey.
All rights reserved (see LICENSE).

*/

#include <fstream>
#include <iostream>
#include <sstream>
#ifndef _WIN32
#include <unistd.h>
#else
#include "getopt_win.h"
#endif

#if USE_LIBOSRM
#include "osrm/exception.hpp"
#endif

#include "problems/vrp.h"
#include "structures/cl_args.h"
#include "utils/helpers.h"
#include "utils/input_parser.h"
#include "utils/output_json.h"
#include "utils/version.h"
#include "utils/exception.h"

void display_usage() {
  std::string usage = "VROOM Copyright (C) 2015-2021, Julien Coupey\n";
  usage += "Version: " + vroom::get_version() + "\n";
  usage += "Usage:\n\tvroom [OPTION]... \"INPUT\"";
  usage += "\n\tvroom [OPTION]... -i FILE\n";
  usage += "\tvroom [OPTION]...\n";
  usage += "Options:\n";
  usage += "\t-a PROFILE:HOST (=" + vroom::DEFAULT_PROFILE +
           ":0.0.0.0)\t routing server\n";
  usage += "\t-c,\t\t\t\t choose ETA for custom routes and report violations\n";
  usage += "\t-g,\t\t\t\t add detailed route geometry and indicators\n";
  usage += "\t-i FILE,\t\t\t read input from FILE rather than from stdin\n";
  usage += "\t-l LIMIT,\t\t\t stop solving process after LIMIT seconds\n";
  usage += "\t-o OUTPUT,\t\t\t output file name\n";
  usage += "\t-p PROFILE:PORT (=" + vroom::DEFAULT_PROFILE +
           ":5000),\t routing server port\n";
  usage += "\t-r ROUTER (=osrm),\t\t osrm, libosrm, ors or valhalla\n";
  usage += "\t-t THREADS (=4),\t\t number of threads to use\n";
  usage += "\t-x EXPLORE (=5),\t\t exploration level to use (0..5)";
  std::cout << usage << std::endl;
  exit(0);
}

int main(int argc, char** argv) {
  // Load default command-line options.
  vroom::io::CLArgs cl_args;

  // Parsing command-line arguments.
  const char* optString = "a:ce:gi:l:o:p:r:t:x:h?";
  int opt = getopt(argc, argv, optString);

  std::string router_arg;
  std::string limit_arg = "";
  std::string nb_threads_arg = std::to_string(cl_args.nb_threads);
  std::string exploration_level_arg = std::to_string(cl_args.exploration_level);
  std::vector<std::string> heuristic_params_arg;

  while (opt != -1) {
    switch (opt) {
    case 'a':
      vroom::io::update_host(cl_args.servers, optarg);
      break;
    case 'c':
      cl_args.check = true;
      break;
    case 'e':
      heuristic_params_arg.push_back(optarg);
      break;
    case 'g':
      cl_args.geometry = true;
      break;
    case 'h':
      display_usage();
      break;
    case 'i':
      cl_args.input_file = optarg;
      break;
    case 'l':
      limit_arg = optarg;
      break;
    case 'o':
      cl_args.output_file = optarg;
      break;
    case 'p':
      vroom::io::update_port(cl_args.servers, optarg);
      break;
    case 'r':
      router_arg = optarg;
      break;
    case 't':
      nb_threads_arg = optarg;
      break;
    case 'x':
      exploration_level_arg = optarg;
      break;
    default:
      break;
    }
    opt = getopt(argc, argv, optString);
  }

  try {
    // Needs to be done after previous switch to make sure the
    // appropriate output file is set.
    if (!limit_arg.empty()) {
      // Internally timeout is in milliseconds.
      cl_args.timeout = 1000 * std::stof(limit_arg);
    }
    cl_args.nb_threads = std::stoul(nb_threads_arg);
    cl_args.exploration_level = std::stoul(exploration_level_arg);

    cl_args.exploration_level =
      std::min(cl_args.exploration_level, cl_args.max_exploration_level);
  } catch (const std::exception& e) {
    auto error_code = vroom::InputException("").error_code;
    std::string message = "Invalid numerical value in option.";
    std::cerr << "[Error] " << message << std::endl;
    vroom::io::write_to_json({error_code, message}, false, cl_args.output_file);
    exit(error_code);
  }

  // Determine routing engine (defaults to ROUTER::OSRM).
  if (router_arg == "libosrm") {
    cl_args.router = vroom::ROUTER::LIBOSRM;
  } else if (router_arg == "ors") {
    cl_args.router = vroom::ROUTER::ORS;
  } else if (router_arg == "valhalla") {
    cl_args.router = vroom::ROUTER::VALHALLA;
  } else if (!router_arg.empty() and router_arg != "osrm") {
    auto error_code = vroom::InputException("").error_code;
    std::string message = "Invalid routing engine: " + router_arg + ".";
    std::cerr << "[Error] " << message << std::endl;
    vroom::io::write_to_json({error_code, message}, false, cl_args.output_file);
    exit(error_code);
  }

  try {
    // Force heuristic parameters from the command-line, useful for
    // debugging.
    std::transform(heuristic_params_arg.begin(),
                   heuristic_params_arg.end(),
                   std::back_inserter(cl_args.h_params),
                   [](const auto& str_param) {
                     return vroom::utils::str_to_heuristic_param(str_param);
                   });
  } catch (const vroom::Exception& e) {
    std::cerr << "[Error] " << e.message << std::endl;
    vroom::io::write_to_json({e.error_code, e.message},
                             false,
                             cl_args.output_file);
    exit(e.error_code);
  }

  // Add default server if none provided in input.
  if (cl_args.servers.empty()) {
    cl_args.servers.emplace(vroom::DEFAULT_PROFILE, vroom::Server());
  }

  // Read input problem
  if (optind == argc) {
    std::stringstream buffer;
    if (cl_args.input_file.empty()) {
      // Getting input from stdin.
      buffer << std::cin.rdbuf();
    } else {
      // Getting input from provided file.
      std::ifstream ifs(cl_args.input_file);
      buffer << ifs.rdbuf();
    }
    cl_args.input = buffer.str();
  } else {
    // Getting input from command-line.
    cl_args.input = argv[optind];
  }

  try {
    // Build problem.
    vroom::Input problem_instance = vroom::io::parse(cl_args);

    vroom::Solution sol = (cl_args.check)
                            ? problem_instance.check(cl_args.nb_threads)
                            : problem_instance.solve(cl_args.exploration_level,
                                                     cl_args.nb_threads,
                                                     cl_args.timeout,
                                                     cl_args.h_params);

    // Write solution.
    vroom::io::write_to_json(sol, cl_args.geometry, cl_args.output_file);
  } catch (const vroom::Exception& e) {
    std::cerr << "[Error] " << e.message << std::endl;
    vroom::io::write_to_json({e.error_code, e.message},
                             false,
                             cl_args.output_file);
    exit(e.error_code);
  }
#if USE_LIBOSRM
  catch (const osrm::exception& e) {
    // In case of an unhandled routing error.
    auto error_code = vroom::RouterException("").error_code;
    auto message = "Routing problem: " + std::string(e.what());
    std::cerr << "[Error] " << message << std::endl;
    vroom::io::write_to_json({error_code, message}, false, cl_args.output_file);
    exit(error_code);
  }
#endif
  catch (const std::exception& e) {
    // In case of an unhandled internal error.
    auto error_code = vroom::InternalException("").error_code;
    std::cerr << "[Error] " << e.what() << std::endl;
    vroom::io::write_to_json({error_code, e.what()},
                             false,
                             cl_args.output_file);
    exit(error_code);
  }

  return 0;
}
<|endoftext|>


<commit_before>/* Copyright 2017 The Apollo Authors. All Rights Reserved.

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 "modules/dreamview/backend/handlers/websocket_handler.h"

#include <cerrno>
#include <utility>
#include <vector>

#include "modules/common/log.h"
#include "modules/common/time/time.h"
#include "modules/common/util/map_util.h"
#include "modules/common/util/string_util.h"

namespace apollo {
namespace dreamview {

using apollo::common::util::ContainsKey;
using apollo::common::util::StrCat;

void WebSocketHandler::handleReadyState(CivetServer *server, Connection *conn) {
  {
    std::unique_lock<std::mutex> lock(mutex_);
    connections_.emplace(conn, std::make_shared<std::mutex>());
    AINFO << "Accepted connection. Total connections: " << connections_.size();
  }

  // Trigger registered new connection handlers.
  for (const auto handler : connection_ready_handlers_) {
    handler(conn);
  }
}

void WebSocketHandler::handleClose(CivetServer *server,
                                   const Connection *conn) {
  {
    std::unique_lock<std::mutex> lock(mutex_);

    // Remove from the store of currently open connections. Copy the mutex out
    // so that it won't be reclaimed during map.erase().
    Connection *connection = const_cast<Connection *>(conn);
    std::shared_ptr<std::mutex> connection_lock = connections_[connection];
    {
      std::unique_lock<std::mutex> lock(*connection_lock);
      connections_.erase(connection);
    }
    AINFO << "Connection closed. Total connections: " << connections_.size();
  }
}

bool WebSocketHandler::BroadcastData(const std::string &data, bool skippable) {
  std::vector<Connection *> connections_to_send;
  {
    std::unique_lock<std::mutex> lock(mutex_);
    if (connections_.empty()) {
      return true;
    }
    for (auto &kv : connections_) {
      Connection *conn = kv.first;
      connections_to_send.push_back(conn);
    }
  }

  bool all_success = true;
  for (Connection *conn : connections_to_send) {
    if (!SendData(conn, data, skippable)) {
      all_success = false;
    }
  }

  return all_success;
}

bool WebSocketHandler::SendBinaryData(Connection *conn, const std::string &data,
                                      bool skippable) {
  return SendData(conn, data, skippable, WEBSOCKET_OPCODE_BINARY);
}

bool WebSocketHandler::SendData(Connection *conn, const std::string &data,
                                bool skippable, int op_code) {
  std::shared_ptr<std::mutex> connection_lock;
  {
    std::unique_lock<std::mutex> lock(mutex_);
    if (!ContainsKey(connections_, conn)) {
      AERROR << "Trying to send to an uncached connection, skipping.";
      return false;
    }
    // Copy the lock so that it still exists if the connection is closed after
    // this block.
    connection_lock = connections_[conn];
  }

  // Lock the connection while sending.
  if (!connection_lock->try_lock()) {
    // Skip sending data if:
    // 1. Data is skippable according to sender and there's higher priority data
    // being sent.
    // 2. The connection has been closed.
    if (skippable) {
      return false;
    } else {
      connection_lock->lock();  // Block to acquire the lock.
      if (!ContainsKey(connections_, conn)) {
        return false;
      }
    }
  }

  // Note that while we are holding the connection lock, the connection won't be
  // closed and removed.
  int ret;
  PERF_BLOCK(StrCat("Writing ", data.size(), " bytes via websocket took"),
             0.1) {
    ret = mg_websocket_write(conn, op_code, data.c_str(), data.size());
  }
  connection_lock->unlock();

  if (ret != static_cast<int>(data.size())) {
    // When data is empty, the header length (2) is returned.
    if (data.size() == 0 && ret == 2) {
      return true;
    }

    // Determine error message based on return value.
    std::string msg;
    if (ret == 0) {
      msg = "Connection Closed";
    } else if (ret < 0) {
      msg = "Send Error: " + std::string(std::strerror(errno));
    } else {
      msg = StrCat("Expect to send ", data.size(), " bytes. But sent ", ret,
                   " bytes");
    }
    AWARN << "Failed to send data via websocket connection. Reason: " << msg;
    return false;
  }

  return true;
}

thread_local unsigned char WebSocketHandler::current_opcode_ = 0x00;
thread_local std::stringstream WebSocketHandler::data_;

bool WebSocketHandler::handleData(CivetServer *server, Connection *conn,
                                  int bits, char *data, size_t data_len) {
  // Ignore connection close request.
  if ((bits & 0x0F) == WEBSOCKET_OPCODE_CONNECTION_CLOSE) {
    return false;
  }

  data_.write(data, data_len);
  if (current_opcode_ == 0x00) {
    current_opcode_ = bits & 0x7f;
  }

  bool result = true;

  // The FIN bit (the left most significant bit) is used to indicates
  // the final fragment in a message. Note, the first fragment MAY
  // also be the final fragment.
  bool is_final_fragment = bits & 0x80;
  if (is_final_fragment) {
    switch (current_opcode_) {
      case WEBSOCKET_OPCODE_TEXT:
        result = handleJsonData(conn, data_.str());
        break;
      case WEBSOCKET_OPCODE_BINARY:
        result = handleBinaryData(conn, data_.str());
        break;
      default:
        AERROR << "Unknown WebSocket bits flag: " << bits;
        break;
    }

    // reset opcode and data
    current_opcode_ = 0x00;
    data_.clear();
    data_.str(std::string());
  }

  return result;
}

bool WebSocketHandler::handleJsonData(Connection *conn,
                                      const std::string &data) {
  Json json;
  try {
    json = Json::parse(data.begin(), data.end());
  } catch (const std::exception &e) {
    AERROR << "Failed to parse JSON data: " << e.what();
    return false;
  }

  if (!ContainsKey(json, "type")) {
    AERROR << "Received JSON data without type field: " << json;
    return true;
  }

  auto type = json["type"];
  if (!ContainsKey(message_handlers_, type)) {
    AERROR << "No message handler found for message type " << type
           << ". The message will be discarded!";
    return true;
  }
  message_handlers_[type](json, conn);
  return true;
}

bool WebSocketHandler::handleBinaryData(Connection *conn,
                                        const std::string &data) {
  auto type = "Binary";
  message_handlers_[type](data, conn);
  return true;
}

}  // namespace dreamview
}  // namespace apollo
<commit_msg>Dreamview: lock the connections map while checking (#3518)<commit_after>/* Copyright 2017 The Apollo Authors. All Rights Reserved.

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 "modules/dreamview/backend/handlers/websocket_handler.h"

#include <cerrno>
#include <utility>
#include <vector>

#include "modules/common/log.h"
#include "modules/common/time/time.h"
#include "modules/common/util/map_util.h"
#include "modules/common/util/string_util.h"

namespace apollo {
namespace dreamview {

using apollo::common::util::ContainsKey;
using apollo::common::util::StrCat;

void WebSocketHandler::handleReadyState(CivetServer *server, Connection *conn) {
  {
    std::unique_lock<std::mutex> lock(mutex_);
    connections_.emplace(conn, std::make_shared<std::mutex>());
    AINFO << "Accepted connection. Total connections: " << connections_.size();
  }

  // Trigger registered new connection handlers.
  for (const auto handler : connection_ready_handlers_) {
    handler(conn);
  }
}

void WebSocketHandler::handleClose(CivetServer *server,
                                   const Connection *conn) {
  {
    std::unique_lock<std::mutex> lock(mutex_);

    // Remove from the store of currently open connections. Copy the mutex out
    // so that it won't be reclaimed during map.erase().
    Connection *connection = const_cast<Connection *>(conn);
    std::shared_ptr<std::mutex> connection_lock = connections_[connection];
    {
      std::unique_lock<std::mutex> lock(*connection_lock);
      connections_.erase(connection);
    }
    AINFO << "Connection closed. Total connections: " << connections_.size();
  }
}

bool WebSocketHandler::BroadcastData(const std::string &data, bool skippable) {
  std::vector<Connection *> connections_to_send;
  {
    std::unique_lock<std::mutex> lock(mutex_);
    if (connections_.empty()) {
      return true;
    }
    for (auto &kv : connections_) {
      Connection *conn = kv.first;
      connections_to_send.push_back(conn);
    }
  }

  bool all_success = true;
  for (Connection *conn : connections_to_send) {
    if (!SendData(conn, data, skippable)) {
      all_success = false;
    }
  }

  return all_success;
}

bool WebSocketHandler::SendBinaryData(Connection *conn, const std::string &data,
                                      bool skippable) {
  return SendData(conn, data, skippable, WEBSOCKET_OPCODE_BINARY);
}

bool WebSocketHandler::SendData(Connection *conn, const std::string &data,
                                bool skippable, int op_code) {
  std::shared_ptr<std::mutex> connection_lock;
  {
    std::unique_lock<std::mutex> lock(mutex_);
    if (!ContainsKey(connections_, conn)) {
      AERROR << "Trying to send to an uncached connection, skipping.";
      return false;
    }
    // Copy the lock so that it still exists if the connection is closed after
    // this block.
    connection_lock = connections_[conn];
  }

  // Lock the connection while sending.
  if (!connection_lock->try_lock()) {
    // Skip sending data if:
    // 1. Data is skippable according to sender and there's higher priority data
    // being sent.
    // 2. The connection has been closed.
    if (skippable) {
      return false;
    } else {
      connection_lock->lock();  // Block to acquire the lock.
      std::unique_lock<std::mutex> lock(mutex_);
      if (!ContainsKey(connections_, conn)) {
        return false;
      }
    }
  }

  // Note that while we are holding the connection lock, the connection won't be
  // closed and removed.
  int ret;
  PERF_BLOCK(StrCat("Writing ", data.size(), " bytes via websocket took"),
             0.1) {
    ret = mg_websocket_write(conn, op_code, data.c_str(), data.size());
  }
  connection_lock->unlock();

  if (ret != static_cast<int>(data.size())) {
    // When data is empty, the header length (2) is returned.
    if (data.size() == 0 && ret == 2) {
      return true;
    }

    // Determine error message based on return value.
    std::string msg;
    if (ret == 0) {
      msg = "Connection Closed";
    } else if (ret < 0) {
      msg = "Send Error: " + std::string(std::strerror(errno));
    } else {
      msg = StrCat("Expect to send ", data.size(), " bytes. But sent ", ret,
                   " bytes");
    }
    AWARN << "Failed to send data via websocket connection. Reason: " << msg;
    return false;
  }

  return true;
}

thread_local unsigned char WebSocketHandler::current_opcode_ = 0x00;
thread_local std::stringstream WebSocketHandler::data_;

bool WebSocketHandler::handleData(CivetServer *server, Connection *conn,
                                  int bits, char *data, size_t data_len) {
  // Ignore connection close request.
  if ((bits & 0x0F) == WEBSOCKET_OPCODE_CONNECTION_CLOSE) {
    return false;
  }

  data_.write(data, data_len);
  if (current_opcode_ == 0x00) {
    current_opcode_ = bits & 0x7f;
  }

  bool result = true;

  // The FIN bit (the left most significant bit) is used to indicates
  // the final fragment in a message. Note, the first fragment MAY
  // also be the final fragment.
  bool is_final_fragment = bits & 0x80;
  if (is_final_fragment) {
    switch (current_opcode_) {
      case WEBSOCKET_OPCODE_TEXT:
        result = handleJsonData(conn, data_.str());
        break;
      case WEBSOCKET_OPCODE_BINARY:
        result = handleBinaryData(conn, data_.str());
        break;
      default:
        AERROR << "Unknown WebSocket bits flag: " << bits;
        break;
    }

    // reset opcode and data
    current_opcode_ = 0x00;
    data_.clear();
    data_.str(std::string());
  }

  return result;
}

bool WebSocketHandler::handleJsonData(Connection *conn,
                                      const std::string &data) {
  Json json;
  try {
    json = Json::parse(data.begin(), data.end());
  } catch (const std::exception &e) {
    AERROR << "Failed to parse JSON data: " << e.what();
    return false;
  }

  if (!ContainsKey(json, "type")) {
    AERROR << "Received JSON data without type field: " << json;
    return true;
  }

  auto type = json["type"];
  if (!ContainsKey(message_handlers_, type)) {
    AERROR << "No message handler found for message type " << type
           << ". The message will be discarded!";
    return true;
  }
  message_handlers_[type](json, conn);
  return true;
}

bool WebSocketHandler::handleBinaryData(Connection *conn,
                                        const std::string &data) {
  auto type = "Binary";
  message_handlers_[type](data, conn);
  return true;
}

}  // namespace dreamview
}  // namespace apollo
<|endoftext|>


<commit_before>#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <unistd.h>
#include <fstream>
#include <iostream>
#include <time.h>
#include <unistd.h>
#include <sys/shm.h>

#include "bcm_host.h"

#include "GLES2/gl2.h"
#include "EGL/egl.h"
#include "EGL/eglext.h"

#include "shader.h"
#include "inotify-cxx.h"

typedef struct {
    uint32_t screen_width;
    uint32_t screen_height;
    // OpenGL|ES objects
    EGLDisplay display;
    EGLSurface surface;
    EGLContext context;

    GLuint buf;

    Shader shader;

} CUBE_STATE_T;

bool* fragHasChanged;
std::string fragFile;
std::string vertSource =
"attribute vec4 a_position;"
"varying vec2 v_texcoord;"
"void main(void) {"
"    gl_Position = a_position;"
"    v_texcoord = a_position.xy*0.5+0.5;"
"}";

static CUBE_STATE_T _state, *state=&_state;

static void init_ogl(CUBE_STATE_T *state){
    int32_t success = 0;
    EGLBoolean result;
    EGLint num_config;

    static EGL_DISPMANX_WINDOW_T nativewindow;

    DISPMANX_ELEMENT_HANDLE_T dispman_element;
    DISPMANX_DISPLAY_HANDLE_T dispman_display;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;

    static const EGLint attribute_list[] = {
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_NONE
    };

    static const EGLint context_attributes[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };
    EGLConfig config;

    // get an EGL display connection
    state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    assert(state->display!=EGL_NO_DISPLAY);

    // initialize the EGL display connection
    result = eglInitialize(state->display, NULL, NULL);
    assert(EGL_FALSE != result);

    // get an appropriate EGL frame buffer configuration
    result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config);
    assert(EGL_FALSE != result);

    // get an appropriate EGL frame buffer configuration
    result = eglBindAPI(EGL_OPENGL_ES_API);
    assert(EGL_FALSE != result);

    // create an EGL rendering context
    state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes);
    assert(state->context!=EGL_NO_CONTEXT);

    // create an EGL window surface
    success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
    assert( success >= 0 );

    dst_rect.x = 0;
    dst_rect.y = 0;
    dst_rect.width = state->screen_width;
    dst_rect.height = state->screen_height;

    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = state->screen_width << 16;
    src_rect.height = state->screen_height << 16;

    dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
    dispman_update = vc_dispmanx_update_start( 0 );
    dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
                                               0/*layer*/, &dst_rect, 0/*src*/,
                                               &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);

    nativewindow.element = dispman_element;
    nativewindow.width = state->screen_width;
    nativewindow.height = state->screen_height;
    vc_dispmanx_update_submit_sync( dispman_update );

    state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL );
    assert(state->surface != EGL_NO_SURFACE);

    // connect the context to the surface
    result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
    assert(EGL_FALSE != result);

    // Set background color and clear buffers
    glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
    glClear( GL_COLOR_BUFFER_BIT );

}

static bool loadFromPath(const std::string& path, std::string* into) {
    std::ifstream file;
    std::string buffer;

    file.open(path.c_str());
    if(!file.is_open()) return false;
    while(!file.eof()) {
        getline(file, buffer);
        (*into) += buffer + "\n";
    }

    file.close();
    return true;
}

static void draw(CUBE_STATE_T *state, GLfloat cx, GLfloat cy){

    if(*fragHasChanged) {
        std::string fragSource;
        if(loadFromPath(fragFile, &fragSource)){
            state->shader.detach(GL_FRAGMENT_SHADER | GL_VERTEX_SHADER);
            state->shader.build(fragSource,vertSource);
            *fragHasChanged = false;
            std::cout << "Parent: reloading shader" << std::endl;
        }
    }

    // Now render to the main frame buffer
    glBindFramebuffer(GL_FRAMEBUFFER,0);
    // Clear the background (not really necessary I suppose)
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glBindBuffer(GL_ARRAY_BUFFER, state->buf);
    state->shader.use();

    state->shader.sendUniform("u_time",((float)clock())/CLOCKS_PER_SEC);
    state->shader.sendUniform("u_mouse",cx, cy);
    state->shader.sendUniform("u_resolution",state->screen_width, state->screen_height);

    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glFlush();
    glFinish();

    eglSwapBuffers(state->display, state->surface);
}

static int get_mouse(CUBE_STATE_T *state, int *outx, int *outy){
    static int fd = -1;
    const int width=state->screen_width, height=state->screen_height;
    static int x=800, y=400;
    const int XSIGN = 1<<4, YSIGN = 1<<5;
    if (fd<0) {
       fd = open("/dev/input/mouse0",O_RDONLY|O_NONBLOCK);
    }
    if (fd>=0) {
        struct {char buttons, dx, dy; } m;
        while (1) {
           int bytes = read(fd, &m, sizeof m);
           if (bytes < (int)sizeof m) goto _exit;
           if (m.buttons&8) {
              break; // This bit should always be set
           }
           read(fd, &m, 1); // Try to sync up again
        }
        if (m.buttons&3)
           return m.buttons&3;
        x+=m.dx;
        y+=m.dy;
        if (m.buttons&XSIGN)
           x-=256;
        if (m.buttons&YSIGN)
           y-=256;
        if (x<0) x=0;
        if (y<0) y=0;
        if (x>width) x=width;
        if (y>height) y=height;
   }
_exit:
   if (outx) *outx = x;
   if (outy) *outy = y;
   return 0;
}

void drawThread() {
    while (1) {
        int x, y, b;
        b = get_mouse(state, &x, &y);
        if (b) break;
        draw(state, x, y);
    }
}

void watchThread(const std::string& file) {
    Inotify notify;

    InotifyWatch watch(file, IN_MODIFY);
    notify.Add(watch);

    for (;;) {
        notify.WaitForEvents();

        if(!(*fragHasChanged)){
            *fragHasChanged = true;
            std::cout << "Child: Something have change" << std::endl;
        }
    }
}

void init(const std::string& fragFile) {
    GLfloat cx, cy;
    bcm_host_init();

    // Clear application state
    memset( state, 0, sizeof( *state ) );

    // Start OGLES
    init_ogl(state);

    //  Build shader;
    //
    std::string fragSource;
    if(!loadFromPath(fragFile, &fragSource)) {
        return;
    }
    state->shader.build(fragSource,vertSource);

    //  Make Quad
    //
    static const GLfloat vertex_data[] = {
        -1.0,-1.0,1.0,1.0,
        1.0,-1.0,1.0,1.0,
        1.0,1.0,1.0,1.0,
        -1.0,1.0,1.0,1.0
    };
    GLint posAttribut = state->shader.getAttribLocation("a_position");

    glClearColor ( 0.0, 1.0, 1.0, 1.0 );

    glGenBuffers(1, &state->buf);

    // Prepare viewport
    glViewport ( 0, 0, state->screen_width, state->screen_height );

    // Upload vertex data to a buffer
    glBindBuffer(GL_ARRAY_BUFFER, state->buf);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data),
                 vertex_data, GL_STATIC_DRAW);
    glVertexAttribPointer(posAttribut, 4, GL_FLOAT, 0, 16, 0);
    glEnableVertexAttribArray(posAttribut);

}

//==============================================================================

int main(int argc, char **argv){

    fragFile = std::string(argv[1]);

    int shmId = shmget(IPC_PRIVATE, sizeof(bool), 0666);

    pid_t pid = fork();

    fragHasChanged = (bool *) shmat(shmId, NULL, 0);

    switch(pid) {
        case -1: //error
        break;

        case 0: // child
        {
            *fragHasChanged = false;
            watchThread(fragFile);
        }
        break;

        default:
        {
            init(fragFile);
            drawThread();

            kill(pid, SIGKILL);
        }
        break;
    }

    shmctl(shmId, IPC_RMID, NULL);

    return 0;
}

<commit_msg>debug<commit_after>#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <unistd.h>
#include <fstream>
#include <iostream>
#include <time.h>
#include <unistd.h>
#include <sys/shm.h>

#include "bcm_host.h"

#include "GLES2/gl2.h"
#include "EGL/egl.h"
#include "EGL/eglext.h"

#include "shader.h"
#include "inotify-cxx.h"

typedef struct {
    uint32_t screen_width;
    uint32_t screen_height;
    // OpenGL|ES objects
    EGLDisplay display;
    EGLSurface surface;
    EGLContext context;

    GLuint buf;

    Shader shader;

} CUBE_STATE_T;

bool* fragHasChanged;
std::string fragFile;
std::string vertSource =
"attribute vec4 a_position;"
"varying vec2 v_texcoord;"
"void main(void) {"
"    gl_Position = a_position;"
"    v_texcoord = a_position.xy*0.5+0.5;"
"}";

static CUBE_STATE_T _state, *state=&_state;

static void init_ogl(CUBE_STATE_T *state){
    int32_t success = 0;
    EGLBoolean result;
    EGLint num_config;

    static EGL_DISPMANX_WINDOW_T nativewindow;

    DISPMANX_ELEMENT_HANDLE_T dispman_element;
    DISPMANX_DISPLAY_HANDLE_T dispman_display;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;

    static const EGLint attribute_list[] = {
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_NONE
    };

    static const EGLint context_attributes[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };
    EGLConfig config;

    // get an EGL display connection
    state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    assert(state->display!=EGL_NO_DISPLAY);

    // initialize the EGL display connection
    result = eglInitialize(state->display, NULL, NULL);
    assert(EGL_FALSE != result);

    // get an appropriate EGL frame buffer configuration
    result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config);
    assert(EGL_FALSE != result);

    // get an appropriate EGL frame buffer configuration
    result = eglBindAPI(EGL_OPENGL_ES_API);
    assert(EGL_FALSE != result);

    // create an EGL rendering context
    state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes);
    assert(state->context!=EGL_NO_CONTEXT);

    // create an EGL window surface
    success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
    assert( success >= 0 );

    dst_rect.x = 0;
    dst_rect.y = 0;
    dst_rect.width = state->screen_width;
    dst_rect.height = state->screen_height;

    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = state->screen_width << 16;
    src_rect.height = state->screen_height << 16;

    dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
    dispman_update = vc_dispmanx_update_start( 0 );
    dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
                                               0/*layer*/, &dst_rect, 0/*src*/,
                                               &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);

    nativewindow.element = dispman_element;
    nativewindow.width = state->screen_width;
    nativewindow.height = state->screen_height;
    vc_dispmanx_update_submit_sync( dispman_update );

    state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL );
    assert(state->surface != EGL_NO_SURFACE);

    // connect the context to the surface
    result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
    assert(EGL_FALSE != result);

    // Set background color and clear buffers
    glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
    glClear( GL_COLOR_BUFFER_BIT );

}

static bool loadFromPath(const std::string& path, std::string* into) {
    std::ifstream file;
    std::string buffer;

    file.open(path.c_str());
    if(!file.is_open()) return false;
    while(!file.eof()) {
        getline(file, buffer);
        (*into) += buffer + "\n";
    }

    file.close();
    return true;
}

static void draw(CUBE_STATE_T *state, GLfloat cx, GLfloat cy){

    if(*fragHasChanged) {
        std::string fragSource;
        if(loadFromPath(fragFile, &fragSource)){
            state->shader.detach(GL_FRAGMENT_SHADER | GL_VERTEX_SHADER);
            state->shader.build(fragSource,vertSource);
            *fragHasChanged = false;
            std::cout << "Parent: reloading shader" << std::endl;
        }
    }

    // Now render to the main frame buffer
    glBindFramebuffer(GL_FRAMEBUFFER,0);
    // Clear the background (not really necessary I suppose)
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glBindBuffer(GL_ARRAY_BUFFER, state->buf);
    state->shader.use();

    state->shader.sendUniform("u_time",((float)clock())/CLOCKS_PER_SEC);
    state->shader.sendUniform("u_mouse",cx, cy);
    state->shader.sendUniform("u_resolution",state->screen_width, state->screen_height);

    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glFlush();
    glFinish();

    eglSwapBuffers(state->display, state->surface);
}

static int get_mouse(CUBE_STATE_T *state, int *outx, int *outy){
    static int fd = -1;
    const int width=state->screen_width, height=state->screen_height;
    static int x=800, y=400;
    const int XSIGN = 1<<4, YSIGN = 1<<5;
    if (fd<0) {
       fd = open("/dev/input/mouse0",O_RDONLY|O_NONBLOCK);
    }
    if (fd>=0) {
        struct {char buttons, dx, dy; } m;
        while (1) {
           int bytes = read(fd, &m, sizeof m);
           if (bytes < (int)sizeof m) goto _exit;
           if (m.buttons&8) {
              break; // This bit should always be set
           }
           read(fd, &m, 1); // Try to sync up again
        }
        if (m.buttons&3)
           return m.buttons&3;
        x+=m.dx;
        y+=m.dy;
        if (m.buttons&XSIGN)
           x-=256;
        if (m.buttons&YSIGN)
           y-=256;
        if (x<0) x=0;
        if (y<0) y=0;
        if (x>width) x=width;
        if (y>height) y=height;
   }
_exit:
   if (outx) *outx = x;
   if (outy) *outy = y;
   return 0;
}

void drawThread() {
    while (1) {
        int x, y, b;
        b = get_mouse(state, &x, &y);
        if (b) break;
        draw(state, x, y);
    }
}

void watchThread(const std::string& file) {
    Inotify notify;

    InotifyWatch watch(file, IN_MODIFY);
    notify.Add(watch);

    for (;;) {
        std::cout << "Child: Watching again" << std::endl;
        notify.WaitForEvents();

        if(!(*fragHasChanged)){
            *fragHasChanged = true;
            std::cout << "Child: Something have change" << std::endl;
        } else {
            std::cout << "Child: should not go there" << std::endl;
        }
    }
}

void init(const std::string& fragFile) {
    GLfloat cx, cy;
    bcm_host_init();

    // Clear application state
    memset( state, 0, sizeof( *state ) );

    // Start OGLES
    init_ogl(state);

    //  Build shader;
    //
    std::string fragSource;
    if(!loadFromPath(fragFile, &fragSource)) {
        return;
    }
    state->shader.build(fragSource,vertSource);

    //  Make Quad
    //
    static const GLfloat vertex_data[] = {
        -1.0,-1.0,1.0,1.0,
        1.0,-1.0,1.0,1.0,
        1.0,1.0,1.0,1.0,
        -1.0,1.0,1.0,1.0
    };
    GLint posAttribut = state->shader.getAttribLocation("a_position");

    glClearColor ( 0.0, 1.0, 1.0, 1.0 );

    glGenBuffers(1, &state->buf);

    // Prepare viewport
    glViewport ( 0, 0, state->screen_width, state->screen_height );

    // Upload vertex data to a buffer
    glBindBuffer(GL_ARRAY_BUFFER, state->buf);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data),
                 vertex_data, GL_STATIC_DRAW);
    glVertexAttribPointer(posAttribut, 4, GL_FLOAT, 0, 16, 0);
    glEnableVertexAttribArray(posAttribut);

}

//==============================================================================

int main(int argc, char **argv){

    fragFile = std::string(argv[1]);

    int shmId = shmget(IPC_PRIVATE, sizeof(bool), 0666);

    pid_t pid = fork();

    fragHasChanged = (bool *) shmat(shmId, NULL, 0);

    switch(pid) {
        case -1: //error
        break;

        case 0: // child
        {
            *fragHasChanged = false;
            watchThread(fragFile);
        }
        break;

        default:
        {
            init(fragFile);
            drawThread();

            kill(pid, SIGKILL);
        }
        break;
    }

    shmctl(shmId, IPC_RMID, NULL);

    return 0;
}

<|endoftext|>


<commit_before>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/renderer/media/media_stream_video_capturer_source.h"

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/location.h"
#include "content/renderer/media/video_capture_impl_manager.h"
#include "content/renderer/render_thread_impl.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/video_frame.h"

namespace {

struct SourceVideoFormat {
  int width;
  int height;
  int frame_rate;
};

// List of formats used if the source doesn't support capability enumeration.
const SourceVideoFormat kVideoFormats[] = {{1920, 1080, 30},
                                           {1280, 720, 30},
                                           {960, 720, 30},
                                           {640, 480, 30},
                                           {640, 360, 30},
                                           {320, 240, 30},
                                           {320, 180, 30}};

}  // namespace

namespace content {

VideoCapturerDelegate::VideoCapturerDelegate(
    const StreamDeviceInfo& device_info)
    : session_id_(device_info.session_id),
      is_screen_cast_(device_info.device.type == MEDIA_TAB_VIDEO_CAPTURE ||
                      device_info.device.type == MEDIA_DESKTOP_VIDEO_CAPTURE),
      got_first_frame_(false) {
  DVLOG(3) << "VideoCapturerDelegate::ctor";

  // NULL in unit test.
  if (RenderThreadImpl::current()) {
    VideoCaptureImplManager* manager =
        RenderThreadImpl::current()->video_capture_impl_manager();
    if (manager)
      release_device_cb_ = manager->UseDevice(session_id_);
  }
}

VideoCapturerDelegate::~VideoCapturerDelegate() {
  DVLOG(3) << "VideoCapturerDelegate::dtor";
  if (!release_device_cb_.is_null())
    release_device_cb_.Run();
}

void VideoCapturerDelegate::GetCurrentSupportedFormats(
    int max_requested_width,
    int max_requested_height,
    const VideoCaptureDeviceFormatsCB& callback) {
  DVLOG(3) << "GetCurrentSupportedFormats("
           << " { max_requested_height = " << max_requested_height << "})"
           << " { max_requested_width = " << max_requested_width << "})";

  if (is_screen_cast_) {
    media::VideoCaptureFormats formats;
    const int width = max_requested_width ?
        max_requested_width : MediaStreamVideoSource::kDefaultWidth;
    const int height = max_requested_height ?
        max_requested_height : MediaStreamVideoSource::kDefaultHeight;
    formats.push_back(
          media::VideoCaptureFormat(
              gfx::Size(width, height),
              MediaStreamVideoSource::kDefaultFrameRate,
              media::PIXEL_FORMAT_I420));
    callback.Run(formats);
    return;
  }

  // NULL in unit test.
  if (!RenderThreadImpl::current())
    return;
  VideoCaptureImplManager* manager =
      RenderThreadImpl::current()->video_capture_impl_manager();
  if (!manager)
    return;
  DCHECK(source_formats_callback_.is_null());
  source_formats_callback_ = callback;
  manager->GetDeviceFormatsInUse(
      session_id_,
      media::BindToCurrentLoop(
          base::Bind(
              &VideoCapturerDelegate::OnDeviceFormatsInUseReceived, this)));
}

void VideoCapturerDelegate::StartCapture(
    const media::VideoCaptureParams& params,
    const VideoCaptureDeliverFrameCB& new_frame_callback,
    const RunningCallback& running_callback) {
  DCHECK(params.requested_format.IsValid());
  DCHECK(thread_checker_.CalledOnValidThread());
  running_callback_ = running_callback;
  got_first_frame_ = false;

  // NULL in unit test.
  if (!RenderThreadImpl::current())
    return;
  VideoCaptureImplManager* manager =
      RenderThreadImpl::current()->video_capture_impl_manager();
  if (!manager)
    return;
  stop_capture_cb_ =
      manager->StartCapture(
          session_id_,
          params,
          media::BindToCurrentLoop(base::Bind(
              &VideoCapturerDelegate::OnStateUpdateOnRenderThread, this)),
          new_frame_callback);
}

void VideoCapturerDelegate::StopCapture() {
  // Immediately make sure we don't provide more frames.
  DVLOG(3) << "VideoCapturerDelegate::StopCapture()";
  DCHECK(thread_checker_.CalledOnValidThread());
  if (!stop_capture_cb_.is_null()) {
    base::ResetAndReturn(&stop_capture_cb_).Run();
  }
  running_callback_.Reset();
  source_formats_callback_.Reset();
}

void VideoCapturerDelegate::OnStateUpdateOnRenderThread(
    VideoCaptureState state) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DVLOG(3) << "OnStateUpdateOnRenderThread state = " << state;
  if (state == VIDEO_CAPTURE_STATE_STARTED && !running_callback_.is_null()) {
    running_callback_.Run(true);
    return;
  }
  if (state > VIDEO_CAPTURE_STATE_STARTED && !running_callback_.is_null()) {
    base::ResetAndReturn(&running_callback_).Run(false);
  }
}

void VideoCapturerDelegate::OnDeviceFormatsInUseReceived(
    const media::VideoCaptureFormats& formats_in_use) {
  DVLOG(3) << "OnDeviceFormatsInUseReceived: " << formats_in_use.size();
  DCHECK(thread_checker_.CalledOnValidThread());
  // StopCapture() might have destroyed |source_formats_callback_| before
  // arriving here.
  if (source_formats_callback_.is_null())
    return;
  // If there are no formats in use, try to retrieve the whole list of
  // supported form.
  if (!formats_in_use.empty()) {
    source_formats_callback_.Run(formats_in_use);
    source_formats_callback_.Reset();
    return;
  }

  // NULL in unit test.
  if (!RenderThreadImpl::current())
    return;
  VideoCaptureImplManager* manager =
      RenderThreadImpl::current()->video_capture_impl_manager();
  if (!manager)
    return;
  manager->GetDeviceSupportedFormats(
      session_id_,
      media::BindToCurrentLoop(
          base::Bind(
              &VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated,
              this)));
}

void VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated(
    const media::VideoCaptureFormats& formats) {
  DVLOG(3) << "OnDeviceSupportedFormatsEnumerated: " << formats.size()
           << " received";
  DCHECK(thread_checker_.CalledOnValidThread());
  // StopCapture() might have destroyed |source_formats_callback_| before
  // arriving here.
  if (source_formats_callback_.is_null())
    return;
  if (formats.size()) {
    source_formats_callback_.Run(formats);
  } else {
    // The capture device doesn't seem to support capability enumeration,
    // compose a fallback list of capabilities.
    media::VideoCaptureFormats default_formats;
    for (size_t i = 0; i < arraysize(kVideoFormats); ++i) {
      default_formats.push_back(media::VideoCaptureFormat(
          gfx::Size(kVideoFormats[i].width, kVideoFormats[i].height),
          kVideoFormats[i].frame_rate,
          media::PIXEL_FORMAT_I420));
    }
    source_formats_callback_.Run(default_formats);
  }
  source_formats_callback_.Reset();
}

MediaStreamVideoCapturerSource::MediaStreamVideoCapturerSource(
    const StreamDeviceInfo& device_info,
    const SourceStoppedCallback& stop_callback,
    const scoped_refptr<VideoCapturerDelegate>& delegate)
    : delegate_(delegate) {
  SetDeviceInfo(device_info);
  SetStopCallback(stop_callback);
}

MediaStreamVideoCapturerSource::~MediaStreamVideoCapturerSource() {
}

void MediaStreamVideoCapturerSource::GetCurrentSupportedFormats(
    int max_requested_width,
    int max_requested_height,
    const VideoCaptureDeviceFormatsCB& callback) {
  delegate_->GetCurrentSupportedFormats(
      max_requested_width,
      max_requested_height,
      callback);
}

void MediaStreamVideoCapturerSource::StartSourceImpl(
    const media::VideoCaptureParams& params,
    const VideoCaptureDeliverFrameCB& frame_callback) {
  media::VideoCaptureParams new_params(params);
  if (device_info().device.type == MEDIA_TAB_VIDEO_CAPTURE ||
      device_info().device.type == MEDIA_DESKTOP_VIDEO_CAPTURE) {
    new_params.allow_resolution_change = true;
  }
  delegate_->StartCapture(
      new_params,
      frame_callback,
      base::Bind(&MediaStreamVideoCapturerSource::OnStartDone,
                 base::Unretained(this)));
}

void MediaStreamVideoCapturerSource::StopSourceImpl() {
  delegate_->StopCapture();
}

}  // namespace content
<commit_msg>Accept up to 60fps frame rate in MediaStreamVideoCapturerSource.<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/renderer/media/media_stream_video_capturer_source.h"

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/location.h"
#include "content/renderer/media/video_capture_impl_manager.h"
#include "content/renderer/render_thread_impl.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/video_frame.h"

namespace {

struct SourceVideoResolution {
  int width;
  int height;
};

// Resolutions used if the source doesn't support capability enumeration.
const SourceVideoResolution kVideoResolutions[] = {{1920, 1080},
                                                   {1280, 720},
                                                   {960, 720},
                                                   {640, 480},
                                                   {640, 360},
                                                   {320, 240},
                                                   {320, 180}};
// Frame rates for sources with no support for capability enumeration.
const int kVideoFrameRates[] = {30, 60};

}  // namespace

namespace content {

VideoCapturerDelegate::VideoCapturerDelegate(
    const StreamDeviceInfo& device_info)
    : session_id_(device_info.session_id),
      is_screen_cast_(device_info.device.type == MEDIA_TAB_VIDEO_CAPTURE ||
                      device_info.device.type == MEDIA_DESKTOP_VIDEO_CAPTURE),
      got_first_frame_(false) {
  DVLOG(3) << "VideoCapturerDelegate::ctor";

  // NULL in unit test.
  if (RenderThreadImpl::current()) {
    VideoCaptureImplManager* manager =
        RenderThreadImpl::current()->video_capture_impl_manager();
    if (manager)
      release_device_cb_ = manager->UseDevice(session_id_);
  }
}

VideoCapturerDelegate::~VideoCapturerDelegate() {
  DVLOG(3) << "VideoCapturerDelegate::dtor";
  if (!release_device_cb_.is_null())
    release_device_cb_.Run();
}

void VideoCapturerDelegate::GetCurrentSupportedFormats(
    int max_requested_width,
    int max_requested_height,
    const VideoCaptureDeviceFormatsCB& callback) {
  DVLOG(3) << "GetCurrentSupportedFormats("
           << " { max_requested_height = " << max_requested_height << "})"
           << " { max_requested_width = " << max_requested_width << "})";

  if (is_screen_cast_) {
    media::VideoCaptureFormats formats;
    const int width = max_requested_width ?
        max_requested_width : MediaStreamVideoSource::kDefaultWidth;
    const int height = max_requested_height ?
        max_requested_height : MediaStreamVideoSource::kDefaultHeight;
    formats.push_back(
          media::VideoCaptureFormat(
              gfx::Size(width, height),
              MediaStreamVideoSource::kDefaultFrameRate,
              media::PIXEL_FORMAT_I420));
    callback.Run(formats);
    return;
  }

  // NULL in unit test.
  if (!RenderThreadImpl::current())
    return;
  VideoCaptureImplManager* manager =
      RenderThreadImpl::current()->video_capture_impl_manager();
  if (!manager)
    return;
  DCHECK(source_formats_callback_.is_null());
  source_formats_callback_ = callback;
  manager->GetDeviceFormatsInUse(
      session_id_,
      media::BindToCurrentLoop(
          base::Bind(
              &VideoCapturerDelegate::OnDeviceFormatsInUseReceived, this)));
}

void VideoCapturerDelegate::StartCapture(
    const media::VideoCaptureParams& params,
    const VideoCaptureDeliverFrameCB& new_frame_callback,
    const RunningCallback& running_callback) {
  DCHECK(params.requested_format.IsValid());
  DCHECK(thread_checker_.CalledOnValidThread());
  running_callback_ = running_callback;
  got_first_frame_ = false;

  // NULL in unit test.
  if (!RenderThreadImpl::current())
    return;
  VideoCaptureImplManager* manager =
      RenderThreadImpl::current()->video_capture_impl_manager();
  if (!manager)
    return;
  stop_capture_cb_ =
      manager->StartCapture(
          session_id_,
          params,
          media::BindToCurrentLoop(base::Bind(
              &VideoCapturerDelegate::OnStateUpdateOnRenderThread, this)),
          new_frame_callback);
}

void VideoCapturerDelegate::StopCapture() {
  // Immediately make sure we don't provide more frames.
  DVLOG(3) << "VideoCapturerDelegate::StopCapture()";
  DCHECK(thread_checker_.CalledOnValidThread());
  if (!stop_capture_cb_.is_null()) {
    base::ResetAndReturn(&stop_capture_cb_).Run();
  }
  running_callback_.Reset();
  source_formats_callback_.Reset();
}

void VideoCapturerDelegate::OnStateUpdateOnRenderThread(
    VideoCaptureState state) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DVLOG(3) << "OnStateUpdateOnRenderThread state = " << state;
  if (state == VIDEO_CAPTURE_STATE_STARTED && !running_callback_.is_null()) {
    running_callback_.Run(true);
    return;
  }
  if (state > VIDEO_CAPTURE_STATE_STARTED && !running_callback_.is_null()) {
    base::ResetAndReturn(&running_callback_).Run(false);
  }
}

void VideoCapturerDelegate::OnDeviceFormatsInUseReceived(
    const media::VideoCaptureFormats& formats_in_use) {
  DVLOG(3) << "OnDeviceFormatsInUseReceived: " << formats_in_use.size();
  DCHECK(thread_checker_.CalledOnValidThread());
  // StopCapture() might have destroyed |source_formats_callback_| before
  // arriving here.
  if (source_formats_callback_.is_null())
    return;
  // If there are no formats in use, try to retrieve the whole list of
  // supported form.
  if (!formats_in_use.empty()) {
    source_formats_callback_.Run(formats_in_use);
    source_formats_callback_.Reset();
    return;
  }

  // NULL in unit test.
  if (!RenderThreadImpl::current())
    return;
  VideoCaptureImplManager* manager =
      RenderThreadImpl::current()->video_capture_impl_manager();
  if (!manager)
    return;
  manager->GetDeviceSupportedFormats(
      session_id_,
      media::BindToCurrentLoop(
          base::Bind(
              &VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated,
              this)));
}

void VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated(
    const media::VideoCaptureFormats& formats) {
  DVLOG(3) << "OnDeviceSupportedFormatsEnumerated: " << formats.size()
           << " received";
  DCHECK(thread_checker_.CalledOnValidThread());
  // StopCapture() might have destroyed |source_formats_callback_| before
  // arriving here.
  if (source_formats_callback_.is_null())
    return;
  if (formats.size()) {
    source_formats_callback_.Run(formats);
  } else {
    // The capture device doesn't seem to support capability enumeration,
    // compose a fallback list of capabilities.
    media::VideoCaptureFormats default_formats;
    for (size_t i = 0; i < arraysize(kVideoResolutions); ++i) {
      for (size_t j = 0; j < arraysize(kVideoFrameRates); ++j) {
        default_formats.push_back(media::VideoCaptureFormat(
            gfx::Size(kVideoResolutions[i].width, kVideoResolutions[i].height),
            kVideoFrameRates[j], media::PIXEL_FORMAT_I420));
      }
    }
    source_formats_callback_.Run(default_formats);
  }
  source_formats_callback_.Reset();
}

MediaStreamVideoCapturerSource::MediaStreamVideoCapturerSource(
    const StreamDeviceInfo& device_info,
    const SourceStoppedCallback& stop_callback,
    const scoped_refptr<VideoCapturerDelegate>& delegate)
    : delegate_(delegate) {
  SetDeviceInfo(device_info);
  SetStopCallback(stop_callback);
}

MediaStreamVideoCapturerSource::~MediaStreamVideoCapturerSource() {
}

void MediaStreamVideoCapturerSource::GetCurrentSupportedFormats(
    int max_requested_width,
    int max_requested_height,
    const VideoCaptureDeviceFormatsCB& callback) {
  delegate_->GetCurrentSupportedFormats(
      max_requested_width,
      max_requested_height,
      callback);
}

void MediaStreamVideoCapturerSource::StartSourceImpl(
    const media::VideoCaptureParams& params,
    const VideoCaptureDeliverFrameCB& frame_callback) {
  media::VideoCaptureParams new_params(params);
  if (device_info().device.type == MEDIA_TAB_VIDEO_CAPTURE ||
      device_info().device.type == MEDIA_DESKTOP_VIDEO_CAPTURE) {
    new_params.allow_resolution_change = true;
  }
  delegate_->StartCapture(
      new_params,
      frame_callback,
      base::Bind(&MediaStreamVideoCapturerSource::OnStartDone,
                 base::Unretained(this)));
}

void MediaStreamVideoCapturerSource::StopSourceImpl() {
  delegate_->StopCapture();
}

}  // namespace content
<|endoftext|>


<commit_before>#ifndef STD_STRING_HPP
#define STD_STRING_HPP

#include "EASTL/string.h"
#include <stdlib.h>

namespace std
{
	using string = eastl::string;

	// std::to_string variants
	inline string to_string(const string& s)
	{
		return s;
	}
	inline string to_string(const char* c)
	{
		return string(c);
	}

	template <class T>
	inline string to_string(T* t)
	{
		// "0x" + (2 per byte as hex value) + zero
		string result(sizeof(T*) * 2 + 3, 0);
		int len = sprintf( (char*) result.data(), "%p", t);
    result.resize(len);

		return result;
	}

	inline string to_string(char c)
	{
		string result(8, 0);
		int len = sprintf( (char*) result.data(), "%hhd", c);
    result.resize(len);

		return result;
	}
	inline string to_string(unsigned char c)
	{
		string result(8, 0);
		int len = sprintf( (char*) result.data(), "%hhu", c);
    result.resize(len);

		return result;
	}

	inline string to_string(short x)
	{
		string result(8, 0);
		int len = sprintf( (char*) result.data(), "%hd", x);
    result.resize(len);

		return result;
	}
	inline string to_string(unsigned short x)
	{
		string result(8, 0);
		int len = sprintf( (char*) result.data(), "%hu", x);
    result.resize(len);

		return result;
	}

	inline string to_string(int x)
	{
		string result(12, 0);
		int len = sprintf( (char*) result.data(), "%d", x);
    result.resize(len);

		return result;
	}
	inline string to_string(unsigned int x)
	{
		string result(12, 0);
		int len = sprintf( (char*) result.data(), "%u", x);
    result.resize(len);

		return result;
	}

	inline string to_string(long x)
	{
		string result(22, 0);
		int len = sprintf( (char*) result.data(), "%ld", x);
    result.resize(len);

		return result;
	}
	inline string to_string(unsigned long x)
	{
		string result(22, 0);
		int len = sprintf( (char*) result.data(), "%lu", x);
    result.resize(len);

		return result;
	}

	inline string to_string(long long x)
	{
		string result(32, 0);
		int len = sprintf( (char*) result.data(), "%lld", x);
    result.resize(len);

		return result;
	}
	inline string to_string(unsigned long long x)
	{
		string result(32, 0);
		int len = sprintf( (char*) result.data(), "%llu", x);
    result.resize(len);

		return result;
	}

	inline string to_string(float x)
	{
		string result(18, 0);
		int len = sprintf( (char*) result.data(), "%f", x);
    result.resize(len);

		return result;
	}
	inline string to_string(double x)
	{
		string result(32, 0);
		int len = sprintf( (char*) result.data(), "%f", x);
    result.resize(len);

		return result;
	}
	inline string to_string(long double x)
	{
		string result(38, 0);
		int len = sprintf( (char*) result.data(), "%Lf", x);
    result.resize(len);

		return result;
	}

	inline int stoi(const string& str, size_t* idx = 0, int base = 10)
	{
		int result = 0;

		if (str.empty())
		{
			if (idx) *idx = 0;
			// TODO: set errno properly (?)
			return result;
		}

		string::const_iterator i = str.begin();
		bool negative = (*i == '-');

		if (negative)
		{
			++i;
			if (i == str.end())
			{
				if (idx) *idx = 0;
				// TODO: set errno properly
				return result;
			}
		}

		for (; i != str.end(); ++i)
		{
			if (*i < '0' || *i > '9')
			{
				if (idx) *idx = str.begin() - i;
				// TODO: set errno properly
				return result;
			}

			result *= base;
			result += *i - '0';
		}

		return (negative) ? -result : result;
    }
}

#endif
<commit_msg>std::to_string(char*)<commit_after>#ifndef STD_STRING_HPP
#define STD_STRING_HPP

#include "EASTL/string.h"
#include <stdlib.h>

namespace std
{
	using string = eastl::string;

	///  std::to_string variants  ///
	inline string to_string(const string& s)
	{
		return s;
	}
	inline string to_string(const char* c)
	{
		return string(c);
	}
	inline string to_string(char* c)
	{
		return string(c);
	}

	template <class T>
	inline string to_string(T* t)
	{
		// "0x" + (2 per byte as hex value) + zero
		string result(sizeof(T*) * 2 + 3, 0);
		int len = sprintf( (char*) result.data(), "%p", t);
    result.resize(len);

		return result;
	}

	inline string to_string(char c)
	{
		string result(8, 0);
		int len = sprintf( (char*) result.data(), "%hhd", c);
    result.resize(len);

		return result;
	}
	inline string to_string(unsigned char c)
	{
		string result(8, 0);
		int len = sprintf( (char*) result.data(), "%hhu", c);
    result.resize(len);

		return result;
	}

	inline string to_string(short x)
	{
		string result(8, 0);
		int len = sprintf( (char*) result.data(), "%hd", x);
    result.resize(len);

		return result;
	}
	inline string to_string(unsigned short x)
	{
		string result(8, 0);
		int len = sprintf( (char*) result.data(), "%hu", x);
    result.resize(len);

		return result;
	}

	inline string to_string(int x)
	{
		string result(12, 0);
		int len = sprintf( (char*) result.data(), "%d", x);
    result.resize(len);

		return result;
	}
	inline string to_string(unsigned int x)
	{
		string result(12, 0);
		int len = sprintf( (char*) result.data(), "%u", x);
    result.resize(len);

		return result;
	}

	inline string to_string(long x)
	{
		string result(22, 0);
		int len = sprintf( (char*) result.data(), "%ld", x);
    result.resize(len);

		return result;
	}
	inline string to_string(unsigned long x)
	{
		string result(22, 0);
		int len = sprintf( (char*) result.data(), "%lu", x);
    result.resize(len);

		return result;
	}

	inline string to_string(long long x)
	{
		string result(32, 0);
		int len = sprintf( (char*) result.data(), "%lld", x);
    result.resize(len);

		return result;
	}
	inline string to_string(unsigned long long x)
	{
		string result(32, 0);
		int len = sprintf( (char*) result.data(), "%llu", x);
    result.resize(len);

		return result;
	}

	inline string to_string(float x)
	{
		string result(18, 0);
		int len = sprintf( (char*) result.data(), "%f", x);
    result.resize(len);

		return result;
	}
	inline string to_string(double x)
	{
		string result(32, 0);
		int len = sprintf( (char*) result.data(), "%f", x);
    result.resize(len);

		return result;
	}
	inline string to_string(long double x)
	{
		string result(38, 0);
		int len = sprintf( (char*) result.data(), "%Lf", x);
    result.resize(len);

		return result;
	}

	inline int stoi(const string& str, size_t* idx = 0, int base = 10)
	{
		int result = 0;

		if (str.empty())
		{
			if (idx) *idx = 0;
			// TODO: set errno properly (?)
			return result;
		}

		string::const_iterator i = str.begin();
		bool negative = (*i == '-');

		if (negative)
		{
			++i;
			if (i == str.end())
			{
				if (idx) *idx = 0;
				// TODO: set errno properly
				return result;
			}
		}

		for (; i != str.end(); ++i)
		{
			if (*i < '0' || *i > '9')
			{
				if (idx) *idx = str.begin() - i;
				// TODO: set errno properly
				return result;
			}

			result *= base;
			result += *i - '0';
		}

		return (negative) ? -result : result;
    }
}

#endif
<|endoftext|>