<commit_before>#include <cbor++/CBORValue.h>

#include <cmath>

#include "util.h"

union uint_conv_u{
  std::uint8_t  byte[8];
  std::uint8_t  i8;
  std::uint16_t i16;
  std::uint32_t i32;
  std::uint64_t i64;
} uint_conv;

std::uint64_t getInteger(const std::uint8_t * bytes, std::uint8_t count)
{
  for(int i = 0; i < count; i++){
    //printf("Setting byte %d to 0x%02x\n", i, bytes[i]);
    uint_conv.byte[i] = bytes[i];
  }

  switch(count){
  case 1:
    return uint_conv.i8;
    break;
  case 2:
    return uint_conv.i16;
    break;
  case 4:
    return uint_conv.i32;
    break;
  case 8:
    return uint_conv.i64;
    break;
  }
  return 0;
}

/*************************
 *
 * Constructors
 *
 *************************/
CBORValue::CBORValue(const std::uint8_t * bytes)
{
  std::uint8_t typeByte = *bytes;

  std::uint8_t mt = getMajorType(typeByte);
  std::uint8_t ai = getAdditionalInfo(typeByte);

  switch(mt) {
  case CBORType_PInt:
    type = CBORType_PInt;
    isNegative = false;
    if(ai <= 23) {
      integerValue = ai;
    } else {
      const std::uint8_t * data = bytes + sizeof(std::uint8_t);
      std::uint8_t count = pow(2,ai-24);
      integerValue = getInteger(data, count);
    }
    break;
  case CBORType_NInt:
    type = CBORType_NInt;
    isNegative = true;
    if(ai <= 23) {
      integerValue = ai;
    } else {
      const std::uint8_t * data = bytes + sizeof(std::uint8_t);
      std::uint8_t count = pow(2,ai-24);
      integerValue = getInteger(data, count);
    }
    break;
  case CBORType_BString:
  case CBORType_UString:
  case CBORType_Array:
  case CBORType_Map:
  default:
    break;
  }
}

/*************************
 *
 * Type Checks
 *
 *************************/
bool CBORValue::isType(CBORType t) const
{
  return type == t;
}

bool CBORValue::isPosInteger() const
{
  return isType(CBORType_PInt);
}

bool CBORValue::isNegInteger() const
{
  return isType(CBORType_NInt);
}

/*************************
 *
 * Value Accessors
 *
 *************************/
std::uint64_t CBORValue::getPosInteger() const
{
  return integerValue;
}

std::int64_t CBORValue::getNegInteger() const
{
  return -1 - integerValue;
}
<commit_msg>Added inital byte string code<commit_after>#include <cbor++/CBORValue.h>

#include <cmath>

#include "util.h"

union uint_conv_u{
  std::uint8_t  byte[8];
  std::uint8_t  i8;
  std::uint16_t i16;
  std::uint32_t i32;
  std::uint64_t i64;
} uint_conv;

std::uint64_t getInteger(const std::uint8_t * bytes, std::uint8_t count)
{
  for(int i = 0; i < count; i++){
    //printf("Setting byte %d to 0x%02x\n", i, bytes[i]);
    uint_conv.byte[i] = bytes[i];
  }

  switch(count){
  case 1:
    return uint_conv.i8;
    break;
  case 2:
    return uint_conv.i16;
    break;
  case 4:
    return uint_conv.i32;
    break;
  case 8:
    return uint_conv.i64;
    break;
  }
  return 0;
}

/*************************
 *
 * Constructors
 *
 *************************/
CBORValue::CBORValue(const std::uint8_t * bytes)
{
  std::uint8_t typeByte = *bytes;

  std::uint8_t mt = getMajorType(typeByte);
  std::uint8_t ai = getAdditionalInfo(typeByte);

  switch(mt) {
  case CBORType_PInt:
    type = CBORType_PInt;
    isNegative = false;
    if(ai <= 23) {
      integerValue = ai;
    } else {
      const std::uint8_t * data = bytes + sizeof(std::uint8_t);
      std::uint8_t count = pow(2,ai-24);
      integerValue = getInteger(data, count);
    }
    break;
  case CBORType_NInt:
    type = CBORType_NInt;
    isNegative = true;
    if(ai <= 23) {
      integerValue = ai;
    } else {
      const std::uint8_t * data = bytes + sizeof(std::uint8_t);
      std::uint8_t count = pow(2,ai-24);
      integerValue = getInteger(data, count);
    }
    break;
  case CBORType_BString: {
    type = CBORType_BString;
    size_t strSize = ai;
    const std::uint8_t * data = bytes;
    if (strSize > 23 && strSize != 31) {
      data = data + sizeof(std::uint8_t);
      std::uint8_t count = pow(2,ai-24);
      strSize = getInteger(data, count);
      data = data + (sizeof(std::uint8_t)*count);
    }
    stringValue = std::string((const char *)data, strSize);
    break;
  }
  case CBORType_UString:
  case CBORType_Array:
  case CBORType_Map:
  default:
    break;
  }
}

/*************************
 *
 * Type Checks
 *
 *************************/
bool CBORValue::isType(CBORType t) const
{
  return type == t;
}

bool CBORValue::isPosInteger() const
{
  return isType(CBORType_PInt);
}

bool CBORValue::isNegInteger() const
{
  return isType(CBORType_NInt);
}

bool CBORValue::isByteString() const
{
  return isType(CBORType_BString);
}

/*************************
 *
 * Value Accessors
 *
 *************************/
std::uint64_t CBORValue::getPosInteger() const
{
  return integerValue;
}

std::int64_t CBORValue::getNegInteger() const
{
  return -1 - integerValue;
}

const std::string CBORValue::getByteString() const
{
  return stringValue;
}
<|endoftext|>


<commit_before>#include <CReadLine.h>
#include <readline/readline.h>
#include <readline/history.h>

using std::string;
using std::vector;

CReadLine *CReadLine::current_ = NULL;

CReadLine::
CReadLine() :
 prompt_("> "), name_("readline"), eof_(false), history_(NULL)
{
  rl_readline_name = name_.c_str();

  rl_catch_signals = 0;

  rl_bind_key('\t'  , (int (*)(int, int)) rlCompleteLine);
  rl_bind_key('\033', (int (*)(int, int)) rlCompleteLine);

  rl_set_key("\\C-d", (int (*)(int, int)) rlShowComplete, rl_get_keymap());

#ifdef OS_WIN
  rl_set_key("\033[0A", (int (*)(int, int)) rlPrevCommand , rl_get_keymap());
  rl_set_key("\033[0B", (int (*)(int, int)) rlNextCommand , rl_get_keymap());
  rl_set_key("\033[0C", rl_named_function("forward-char" ), rl_get_keymap());
  rl_set_key("\033[0D", rl_named_function("backward-char"), rl_get_keymap());
#endif

  rl_set_key("\033[A", (int (*)(int, int)) rlPrevCommand , rl_get_keymap());
  rl_set_key("\033[B", (int (*)(int, int)) rlNextCommand , rl_get_keymap());
  rl_set_key("\033[C", rl_named_function("forward-char" ), rl_get_keymap());
  rl_set_key("\033[D", rl_named_function("backward-char"), rl_get_keymap());

  rl_set_key("\033[OA", (int (*)(int, int)) rlPrevCommand , rl_get_keymap());
  rl_set_key("\033[OB", (int (*)(int, int)) rlNextCommand , rl_get_keymap());
  rl_set_key("\033[OC", rl_named_function("forward-char" ), rl_get_keymap());
  rl_set_key("\033[OD", rl_named_function("backward-char"), rl_get_keymap());
}

void
CReadLine::
setAutoHistory(bool flag)
{
  delete history_;

  if (flag)
    history_ = new CHistory();
  else
    history_ = NULL;
}

void
CReadLine::
enableTimoutHook()
{
  rl_event_hook = rlEventHook;
}

void
CReadLine::
disableTimoutHook()
{
  rl_event_hook = NULL;
}

string
CReadLine::
readLine()
{
  current_ = this;

  char *p = ::readline((char *) prompt_.c_str());

  if (p == NULL) {
    eof_ = true;

    return "";
  }

  if (history_ != NULL)
    addHistory(p);

  return p;
}

void
CReadLine::
setPrompt(const string &prompt)
{
  prompt_ = prompt;
}

void
CReadLine::
setName(const string &name)
{
  name_ = name;

  rl_readline_name = name_.c_str();
}

bool
CReadLine::
getPrevCommand(string &line)
{
  if (history_ != NULL)
    return history_->getPrevCommand(line);
  else
    return false;
}

bool
CReadLine::
getNextCommand(string &line)
{
  if (history_ != NULL)
    return history_->getNextCommand(line);
  else
    return false;
}

int
CReadLine::
rlCompleteLine(int, int)
{
  if (rl_point != rl_end)
    return 0;

  string line = current_->getBuffer();

  string line1;

  if (current_->completeLine(line, line1))
    current_->setBuffer(line + line1);

  return 0;
}

int
CReadLine::
rlShowComplete(int, int)
{
  if (rl_point != rl_end) {
    rl_end = rl_point;

    rl_line_buffer[rl_end] = '\0';
  }
  else {
    string line = current_->getBuffer();

    if (current_->showComplete(line))
      rl_forced_update_display();
  }

  return 0;
}

int
CReadLine::
rlPrevCommand(int, int)
{
  string line;

  if (current_->getPrevCommand(line))
    current_->setBuffer(line);

  return 0;
}

int
CReadLine::
rlNextCommand(int, int)
{
  string line;

  if (! current_->getNextCommand(line))
    line = "";

  current_->setBuffer(line);

  return 0;
}

int
CReadLine::
rlEventHook()
{
  current_->timeout();

  return 1;
}

string
CReadLine::
getBuffer() const
{
  return rl_line_buffer;
}

void
CReadLine::
setBuffer(const string &buffer)
{
  rl_extend_line_buffer(buffer.size() + 1);

  strcpy(rl_line_buffer, buffer.c_str());

  rl_end = buffer.size();

  rl_point = rl_end;
}

void
CReadLine::
addHistory(const string &line)
{
  if (history_ == NULL)
    history_ = new CHistory;

  history_->addCommand(line);
}

void
CReadLine::
getHistoryEntries(vector<CReadLineHistoryEntry> &entries)
{
  HIST_ENTRY **hist_entries = history_list();

  for (int i = 0; hist_entries != NULL && hist_entries[i] != NULL; i++) {
    CReadLineHistoryEntry entry(i + history_base, hist_entries[i]->line);

    entries.push_back(entry);
  }
}

void
CReadLine::
beep()
{
  rl_ding();
}

void
CReadLine::
interrupt()
{
  rl_crlf();

  setBuffer("");

  rl_forced_update_display();
}
<commit_msg>new files<commit_after>#include <CReadLine.h>
#include <readline/readline.h>
#include <readline/history.h>

CReadLine *CReadLine::current_ = NULL;

CReadLine::
CReadLine() :
 prompt_("> "), name_("readline"), eof_(false), history_(NULL)
{
  rl_readline_name = name_.c_str();

  rl_catch_signals = 0;

  rl_bind_key('\t'  , (int (*)(int, int)) rlCompleteLine);
  rl_bind_key('\033', (int (*)(int, int)) rlCompleteLine);

  rl_set_key("\\C-d", (int (*)(int, int)) rlShowComplete, rl_get_keymap());

#ifdef OS_WIN
  rl_set_key("\033[0A", (int (*)(int, int)) rlPrevCommand , rl_get_keymap());
  rl_set_key("\033[0B", (int (*)(int, int)) rlNextCommand , rl_get_keymap());
  rl_set_key("\033[0C", rl_named_function("forward-char" ), rl_get_keymap());
  rl_set_key("\033[0D", rl_named_function("backward-char"), rl_get_keymap());
#endif

  rl_set_key("\033[A", (int (*)(int, int)) rlPrevCommand , rl_get_keymap());
  rl_set_key("\033[B", (int (*)(int, int)) rlNextCommand , rl_get_keymap());
  rl_set_key("\033[C", rl_named_function("forward-char" ), rl_get_keymap());
  rl_set_key("\033[D", rl_named_function("backward-char"), rl_get_keymap());

  rl_set_key("\033[OA", (int (*)(int, int)) rlPrevCommand , rl_get_keymap());
  rl_set_key("\033[OB", (int (*)(int, int)) rlNextCommand , rl_get_keymap());
  rl_set_key("\033[OC", rl_named_function("forward-char" ), rl_get_keymap());
  rl_set_key("\033[OD", rl_named_function("backward-char"), rl_get_keymap());
}

void
CReadLine::
setAutoHistory(bool flag)
{
  delete history_;

  if (flag)
    history_ = new CHistory();
  else
    history_ = NULL;
}

void
CReadLine::
enableTimoutHook()
{
  rl_event_hook = rlEventHook;
}

void
CReadLine::
disableTimoutHook()
{
  rl_event_hook = NULL;
}

std::string
CReadLine::
readLine()
{
  current_ = this;

  char *p = ::readline((char *) prompt_.c_str());

  if (p == NULL) {
    eof_ = true;

    return "";
  }

  if (history_ != NULL)
    addHistory(p);

  return p;
}

void
CReadLine::
setPrompt(const std::string &prompt)
{
  prompt_ = prompt;
}

void
CReadLine::
setName(const std::string &name)
{
  name_ = name;

  rl_readline_name = name_.c_str();
}

bool
CReadLine::
getPrevCommand(std::string &line)
{
  if (history_ != NULL)
    return history_->getPrevCommand(line);
  else
    return false;
}

bool
CReadLine::
getNextCommand(std::string &line)
{
  if (history_ != NULL)
    return history_->getNextCommand(line);
  else
    return false;
}

int
CReadLine::
rlCompleteLine(int, int)
{
  if (rl_point != rl_end)
    return 0;

  std::string line = current_->getBuffer();

  std::string line1;

  if (current_->completeLine(line, line1))
    current_->setBuffer(line + line1);

  return 0;
}

int
CReadLine::
rlShowComplete(int, int)
{
  if (rl_point != rl_end) {
    rl_end = rl_point;

    rl_line_buffer[rl_end] = '\0';
  }
  else {
    std::string line = current_->getBuffer();

    if (current_->showComplete(line))
      rl_forced_update_display();
  }

  return 0;
}

int
CReadLine::
rlPrevCommand(int, int)
{
  std::string line;

  if (current_->getPrevCommand(line))
    current_->setBuffer(line);

  return 0;
}

int
CReadLine::
rlNextCommand(int, int)
{
  std::string line;

  if (! current_->getNextCommand(line))
    line = "";

  current_->setBuffer(line);

  return 0;
}

int
CReadLine::
rlEventHook()
{
  current_->timeout();

  return 1;
}

std::string
CReadLine::
getBuffer() const
{
  return rl_line_buffer;
}

void
CReadLine::
setBuffer(const std::string &buffer)
{
  rl_extend_line_buffer(buffer.size() + 1);

  strcpy(rl_line_buffer, buffer.c_str());

  rl_end = buffer.size();

  rl_point = rl_end;
}

void
CReadLine::
addHistory(const std::string &line)
{
  if (history_ == NULL)
    history_ = new CHistory;

  history_->addCommand(line);
}

void
CReadLine::
getHistoryEntries(std::vector<CReadLineHistoryEntry> &entries)
{
  HIST_ENTRY **hist_entries = history_list();

  for (int i = 0; hist_entries != NULL && hist_entries[i] != NULL; i++) {
    CReadLineHistoryEntry entry(i + history_base, hist_entries[i]->line);

    entries.push_back(entry);
  }
}

void
CReadLine::
beep()
{
  rl_ding();
}

void
CReadLine::
interrupt()
{
  rl_crlf();

  setBuffer("");

  rl_forced_update_display();
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 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/browser/speech/speech_recognition_request.h"

#include <vector>

#include "base/json/json_reader.h"
#include "base/string_util.h"
#include "base/values.h"
#include "chrome/common/net/url_request_context_getter.h"
#include "net/base/escape.h"
#include "net/base/load_flags.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_status.h"
#include "ui/base/l10n/l10n_util.h"

namespace {

const char* const kDefaultSpeechRecognitionUrl =
    "https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&";
const char* const kHypothesesString = "hypotheses";
const char* const kUtteranceString = "utterance";
const char* const kConfidenceString = "confidence";

bool ParseServerResponse(const std::string& response_body,
                         speech_input::SpeechInputResultArray* result) {
  if (response_body.empty()) {
    LOG(WARNING) << "ParseServerResponse: Response was empty.";
    return false;
  }
  DVLOG(1) << "ParseServerResponse: Parsing response " << response_body;

  // Parse the response, ignoring comments.
  std::string error_msg;
  scoped_ptr<Value> response_value(base::JSONReader::ReadAndReturnError(
      response_body, false, NULL, &error_msg));
  if (response_value == NULL) {
    LOG(WARNING) << "ParseServerResponse: JSONReader failed : " << error_msg;
    return false;
  }

  if (!response_value->IsType(Value::TYPE_DICTIONARY)) {
    VLOG(1) << "ParseServerResponse: Unexpected response type "
            << response_value->GetType();
    return false;
  }
  const DictionaryValue* response_object =
      static_cast<DictionaryValue*>(response_value.get());

  // Get the hypotheses
  Value* hypotheses_value = NULL;
  if (!response_object->Get(kHypothesesString, &hypotheses_value)) {
    VLOG(1) << "ParseServerResponse: Missing hypotheses attribute.";
    return false;
  }
  DCHECK(hypotheses_value);
  if (!hypotheses_value->IsType(Value::TYPE_LIST)) {
    VLOG(1) << "ParseServerResponse: Unexpected hypotheses type "
            << hypotheses_value->GetType();
    return false;
  }
  const ListValue* hypotheses_list = static_cast<ListValue*>(hypotheses_value);

  size_t index = 0;
  for (; index < hypotheses_list->GetSize(); ++index) {
    Value* hypothesis = NULL;
    if (!hypotheses_list->Get(index, &hypothesis)) {
      LOG(WARNING) << "ParseServerResponse: Unable to read hypothesis value.";
      break;
    }
    DCHECK(hypothesis);
    if (!hypothesis->IsType(Value::TYPE_DICTIONARY)) {
      LOG(WARNING) << "ParseServerResponse: Unexpected value type "
                   << hypothesis->GetType();
      break;
    }

    const DictionaryValue* hypothesis_value =
        static_cast<DictionaryValue*>(hypothesis);
    string16 utterance;
    if (!hypothesis_value->GetString(kUtteranceString, &utterance)) {
      LOG(WARNING) << "ParseServerResponse: Missing utterance value.";
      break;
    }

    // It is not an error if the 'confidence' field is missing.
    double confidence = 0.0;
    hypothesis_value->GetDouble(kConfidenceString, &confidence);

    result->push_back(speech_input::SpeechInputResultItem(utterance,
                                                          confidence));
  }

  if (index < hypotheses_list->GetSize()) {
    result->clear();
    return false;
  }

  return true;
}

}  // namespace

namespace speech_input {

int SpeechRecognitionRequest::url_fetcher_id_for_tests = 0;

SpeechRecognitionRequest::SpeechRecognitionRequest(
    URLRequestContextGetter* context, Delegate* delegate)
    : url_context_(context),
      delegate_(delegate) {
  DCHECK(delegate);
}

SpeechRecognitionRequest::~SpeechRecognitionRequest() {}

void SpeechRecognitionRequest::Start(const std::string& language,
                                     const std::string& grammar,
                                     const std::string& hardware_info,
                                     const std::string& origin_url,
                                     const std::string& content_type) {
  DCHECK(!url_fetcher_.get());

  std::vector<std::string> parts;

  std::string lang_param = language;
  if (lang_param.empty() && url_context_) {
    // If no language is provided then we use the first from the accepted
    // language list. If this list is empty then it defaults to "en-US".
    // Example of the contents of this list: "es,en-GB;q=0.8", ""
    net::URLRequestContext* request_context =
        url_context_->GetURLRequestContext();
    DCHECK(request_context);
    std::string accepted_language_list = request_context->accept_language();
    size_t separator = accepted_language_list.find_first_of(",;");
    lang_param = accepted_language_list.substr(0, separator);
  }
  if (lang_param.empty())
    lang_param = "en-US";
  parts.push_back("lang=" + EscapeQueryParamValue(lang_param, true));

  if (!grammar.empty())
    parts.push_back("lm=" + EscapeQueryParamValue(grammar, true));
  if (!hardware_info.empty())
    parts.push_back("xhw=" + EscapeQueryParamValue(hardware_info, true));
  // TODO(satish): Remove this hardcoded value once the page is allowed to
  // set this via an attribute.
  parts.push_back("maxresults=3");

  GURL url(std::string(kDefaultSpeechRecognitionUrl) + JoinString(parts, '&'));

  url_fetcher_.reset(URLFetcher::Create(url_fetcher_id_for_tests,
                                        url,
                                        URLFetcher::POST,
                                        this));
  url_fetcher_->set_chunked_upload(content_type);
  url_fetcher_->set_request_context(url_context_);
  url_fetcher_->set_referrer(origin_url);

  // The speech recognition API does not require user identification as part
  // of requests, so we don't send cookies or auth data for these requests to
  // prevent any accidental connection between users who are logged into the
  // domain for other services (e.g. bookmark sync) with the speech requests.
  url_fetcher_->set_load_flags(
      net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES |
      net::LOAD_DO_NOT_SEND_AUTH_DATA);
  url_fetcher_->Start();
}

void SpeechRecognitionRequest::UploadAudioChunk(const std::string& audio_data,
                                                bool is_last_chunk) {
  DCHECK(url_fetcher_.get());
  url_fetcher_->AppendChunkToUpload(audio_data, is_last_chunk);
}

void SpeechRecognitionRequest::OnURLFetchComplete(
    const URLFetcher* source,
    const GURL& url,
    const net::URLRequestStatus& status,
    int response_code,
    const ResponseCookies& cookies,
    const std::string& data) {
  DCHECK_EQ(url_fetcher_.get(), source);

  bool error = !status.is_success() || response_code != 200;
  SpeechInputResultArray result;
  if (!error)
    error = !ParseServerResponse(data, &result);
  url_fetcher_.reset();

  DVLOG(1) << "SpeechRecognitionRequest: Invoking delegate with result.";
  delegate_->SetRecognitionResult(error, result);
}

}  // namespace speech_input
<commit_msg>Request for 5 speech recognition results instead of 3. This will give webapps more choice until we implement the maxresults attribute.<commit_after>// Copyright (c) 2011 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/browser/speech/speech_recognition_request.h"

#include <vector>

#include "base/json/json_reader.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/values.h"
#include "chrome/common/net/url_request_context_getter.h"
#include "net/base/escape.h"
#include "net/base/load_flags.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_status.h"
#include "ui/base/l10n/l10n_util.h"

namespace {

const char* const kDefaultSpeechRecognitionUrl =
    "https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&";
const char* const kHypothesesString = "hypotheses";
const char* const kUtteranceString = "utterance";
const char* const kConfidenceString = "confidence";

// TODO(satish): Remove this hardcoded value once the page is allowed to
// set this via an attribute.
const int kMaxResults = 5;

bool ParseServerResponse(const std::string& response_body,
                         speech_input::SpeechInputResultArray* result) {
  if (response_body.empty()) {
    LOG(WARNING) << "ParseServerResponse: Response was empty.";
    return false;
  }
  DVLOG(1) << "ParseServerResponse: Parsing response " << response_body;

  // Parse the response, ignoring comments.
  std::string error_msg;
  scoped_ptr<Value> response_value(base::JSONReader::ReadAndReturnError(
      response_body, false, NULL, &error_msg));
  if (response_value == NULL) {
    LOG(WARNING) << "ParseServerResponse: JSONReader failed : " << error_msg;
    return false;
  }

  if (!response_value->IsType(Value::TYPE_DICTIONARY)) {
    VLOG(1) << "ParseServerResponse: Unexpected response type "
            << response_value->GetType();
    return false;
  }
  const DictionaryValue* response_object =
      static_cast<DictionaryValue*>(response_value.get());

  // Get the hypotheses
  Value* hypotheses_value = NULL;
  if (!response_object->Get(kHypothesesString, &hypotheses_value)) {
    VLOG(1) << "ParseServerResponse: Missing hypotheses attribute.";
    return false;
  }
  DCHECK(hypotheses_value);
  if (!hypotheses_value->IsType(Value::TYPE_LIST)) {
    VLOG(1) << "ParseServerResponse: Unexpected hypotheses type "
            << hypotheses_value->GetType();
    return false;
  }
  const ListValue* hypotheses_list = static_cast<ListValue*>(hypotheses_value);

  size_t index = 0;
  for (; index < hypotheses_list->GetSize(); ++index) {
    Value* hypothesis = NULL;
    if (!hypotheses_list->Get(index, &hypothesis)) {
      LOG(WARNING) << "ParseServerResponse: Unable to read hypothesis value.";
      break;
    }
    DCHECK(hypothesis);
    if (!hypothesis->IsType(Value::TYPE_DICTIONARY)) {
      LOG(WARNING) << "ParseServerResponse: Unexpected value type "
                   << hypothesis->GetType();
      break;
    }

    const DictionaryValue* hypothesis_value =
        static_cast<DictionaryValue*>(hypothesis);
    string16 utterance;
    if (!hypothesis_value->GetString(kUtteranceString, &utterance)) {
      LOG(WARNING) << "ParseServerResponse: Missing utterance value.";
      break;
    }

    // It is not an error if the 'confidence' field is missing.
    double confidence = 0.0;
    hypothesis_value->GetDouble(kConfidenceString, &confidence);

    result->push_back(speech_input::SpeechInputResultItem(utterance,
                                                          confidence));
  }

  if (index < hypotheses_list->GetSize()) {
    result->clear();
    return false;
  }

  return true;
}

}  // namespace

namespace speech_input {

int SpeechRecognitionRequest::url_fetcher_id_for_tests = 0;

SpeechRecognitionRequest::SpeechRecognitionRequest(
    URLRequestContextGetter* context, Delegate* delegate)
    : url_context_(context),
      delegate_(delegate) {
  DCHECK(delegate);
}

SpeechRecognitionRequest::~SpeechRecognitionRequest() {}

void SpeechRecognitionRequest::Start(const std::string& language,
                                     const std::string& grammar,
                                     const std::string& hardware_info,
                                     const std::string& origin_url,
                                     const std::string& content_type) {
  DCHECK(!url_fetcher_.get());

  std::vector<std::string> parts;

  std::string lang_param = language;
  if (lang_param.empty() && url_context_) {
    // If no language is provided then we use the first from the accepted
    // language list. If this list is empty then it defaults to "en-US".
    // Example of the contents of this list: "es,en-GB;q=0.8", ""
    net::URLRequestContext* request_context =
        url_context_->GetURLRequestContext();
    DCHECK(request_context);
    std::string accepted_language_list = request_context->accept_language();
    size_t separator = accepted_language_list.find_first_of(",;");
    lang_param = accepted_language_list.substr(0, separator);
  }
  if (lang_param.empty())
    lang_param = "en-US";
  parts.push_back("lang=" + EscapeQueryParamValue(lang_param, true));

  if (!grammar.empty())
    parts.push_back("lm=" + EscapeQueryParamValue(grammar, true));
  if (!hardware_info.empty())
    parts.push_back("xhw=" + EscapeQueryParamValue(hardware_info, true));
  parts.push_back("maxresults=" + base::IntToString(kMaxResults));

  GURL url(std::string(kDefaultSpeechRecognitionUrl) + JoinString(parts, '&'));

  url_fetcher_.reset(URLFetcher::Create(url_fetcher_id_for_tests,
                                        url,
                                        URLFetcher::POST,
                                        this));
  url_fetcher_->set_chunked_upload(content_type);
  url_fetcher_->set_request_context(url_context_);
  url_fetcher_->set_referrer(origin_url);

  // The speech recognition API does not require user identification as part
  // of requests, so we don't send cookies or auth data for these requests to
  // prevent any accidental connection between users who are logged into the
  // domain for other services (e.g. bookmark sync) with the speech requests.
  url_fetcher_->set_load_flags(
      net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES |
      net::LOAD_DO_NOT_SEND_AUTH_DATA);
  url_fetcher_->Start();
}

void SpeechRecognitionRequest::UploadAudioChunk(const std::string& audio_data,
                                                bool is_last_chunk) {
  DCHECK(url_fetcher_.get());
  url_fetcher_->AppendChunkToUpload(audio_data, is_last_chunk);
}

void SpeechRecognitionRequest::OnURLFetchComplete(
    const URLFetcher* source,
    const GURL& url,
    const net::URLRequestStatus& status,
    int response_code,
    const ResponseCookies& cookies,
    const std::string& data) {
  DCHECK_EQ(url_fetcher_.get(), source);

  bool error = !status.is_success() || response_code != 200;
  SpeechInputResultArray result;
  if (!error)
    error = !ParseServerResponse(data, &result);
  url_fetcher_.reset();

  DVLOG(1) << "SpeechRecognitionRequest: Invoking delegate with result.";
  delegate_->SetRecognitionResult(error, result);
}

}  // namespace speech_input
<|endoftext|>


<commit_before>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2016-2021 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include <modules/animationqt/animationqtmodule.h>
#include <inviwo/core/properties/ordinalproperty.h>
#include <inviwo/core/common/inviwoapplication.h>
#include <inviwo/core/util/raiiutils.h>

#include <modules/qtwidgets/inviwoqtutils.h>

#include <modules/animation/animationmodule.h>
#include <modules/animation/datastructures/animation.h>
#include <modules/animation/datastructures/buttontrack.h>
#include <modules/animation/datastructures/cameratrack.h>
#include <modules/animation/datastructures/callbacktrack.h>
#include <modules/animation/datastructures/controltrack.h>
#include <modules/animation/datastructures/keyframe.h>
#include <modules/animation/datastructures/propertytrack.h>
#include <modules/animation/datastructures/valuekeyframe.h>
#include <modules/animation/datastructures/track.h>
#include <modules/animation/animationcontroller.h>

#include <modules/animationqt/animationeditordockwidgetqt.h>
#include <modules/animationqt/demo/demonavigatordockwidgetqt.h>

#include <modules/animationqt/widgets/propertytrackwidgetqt.h>
#include <modules/animationqt/widgets/controltrackwidgetqt.h>

#include <modules/animationqt/sequenceeditor/propertysequenceeditor.h>
#include <modules/animationqt/sequenceeditor/controlsequenceeditor.h>

#include <inviwo/core/properties/boolproperty.h>
#include <inviwo/core/properties/buttonproperty.h>
#include <inviwo/core/properties/cameraproperty.h>
#include <inviwo/core/properties/fileproperty.h>
#include <inviwo/core/properties/minmaxproperty.h>
#include <inviwo/core/properties/optionproperty.h>
#include <inviwo/core/properties/ordinalproperty.h>
#include <inviwo/core/properties/ordinalrefproperty.h>
#include <inviwo/core/properties/stringproperty.h>

#include <warn/push>
#include <warn/ignore/all>
#include <QMenu>
#include <QMainWindow>
#include <QMenuBar>
#include <QAction>
#include <warn/pop>

#ifndef INVIWO_ALL_DYN_LINK
struct InitQtAnimationResources {
    // Needed for loading of resources when building statically
    // see https://wiki.qt.io/QtResources#Q_INIT_RESOURCE
    InitQtAnimationResources() { Q_INIT_RESOURCE(animation); }
    ~InitQtAnimationResources() { Q_CLEANUP_RESOURCE(animation); }
} initQtAnimationResources;
#endif

namespace inviwo {

namespace {

template <typename PropertyType, typename Keyframe,
          typename KeyframeSequence = animation::KeyframeSequenceTyped<Keyframe>>
void registerPropertyTrackHelper(animation::AnimationQtSupplier& as) {
    using namespace animation;

    using TrackType = PropertyTrack<PropertyType, Keyframe, KeyframeSequence>;

    as.registerTrackToWidgetMap(TrackType::classIdentifier(),
                                PropertyTrackWidgetQt::classIdentifier());

    as.registerTrackToSequenceEditorMap(TrackType::classIdentifier(),
                                        PropertySequenceEditor::classIdentifier());
}

template <template <typename> class Prop>
struct Reghelper {
    template <typename T>
    auto operator()(animation::AnimationQtSupplier& as) {
        using namespace animation;
        registerPropertyTrackHelper<Prop<T>, ValueKeyframe<typename Prop<T>::value_type>>(as);
    }
};

struct PropertyValueKeyframeReghelper {
    template <typename Prop>
    auto operator()(animation::AnimationQtSupplier& as) {
        using namespace animation;
        registerPropertyTrackHelper<Prop, ValueKeyframe<typename Prop::value_type>>(as);
    }
};

}  // namespace

AnimationQtModule::AnimationQtModule(InviwoApplication* app)
    : InviwoModule(app, "AnimationQt")
    , animation::AnimationQtSupplier(*this)
    , trackWidgetQtFactory_{}
    , sequenceEditorFactory_{} {

    using namespace animation;

    if (auto win = utilqt::getApplicationMainWindow()) {
        QString animationMenuName("Animation");
        QMenu* menu = nullptr;
        // Find view menu
        auto menus = win->menuBar()->findChildren<QMenu*>();
        auto viewMenuIt = std::find_if(menus.begin(), menus.end(), [](auto& m) {
            return m->title().compare(QObject::tr("&View"), Qt::CaseInsensitive) == 0;
        });

        if (viewMenuIt != menus.end()) {
            // Add to view menu if found
            menu = (*viewMenuIt);
        } else {
            // Add new menu if not found
            // To be removed when module is destroyed
            menu_ = std::make_unique<QMenu>(animationMenuName);
            win->menuBar()->addMenu(menu_.get());
            menu = menu_.get();
            // Release pointer if destroyed by Qt before module is destroyed
            QObject::connect(menu_.get(), &QObject::destroyed, [&](QObject*) { menu_.release(); });
        }

        {
            auto action = menu->addAction("Animation Editor");
            action->setCheckable(true);
            QObject::connect(action, &QAction::triggered, [this, win, app, menu, action]() {
                util::OnScopeExit onexit([action]() { delete action; });

                auto animationModule = app->getModuleByType<AnimationModule>();
                editor_ = std::make_unique<AnimationEditorDockWidgetQt>(
                    animationModule->getWorkspaceAnimations(),
                    animationModule->getAnimationManager(), "Animation Editor",
                    getTrackWidgetQtFactory(), getSequenceEditorFactory(), win);
                win->addDockWidget(Qt::BottomDockWidgetArea, editor_.get());
                editor_->hide();
                editor_->loadState();
                // Release pointer if destroyed by Qt before module is destroyed
                QObject::connect(editor_.get(), &QObject::destroyed,
                                 [this](QObject*) { editor_.release(); });
                editor_->setVisible(true);

                menu->insertAction(action, editor_->toggleViewAction());
                menu->removeAction(action);
            });
        }

        {
            auto action = menu->addAction("Demo Navigator");
            action->setCheckable(true);
            QObject::connect(action, &QAction::triggered, [this, win, app, menu, action]() {
                util::OnScopeExit onexit([action]() { delete action; });

                auto animationModule = app->getModuleByType<AnimationModule>();
                auto& demoController = animationModule->getDemoController();
                navigator_ = std::make_unique<DemoNavigatorDockWidgetQt>(demoController,
                                                                         "Demo Navigator", win);
                win->addDockWidget(Qt::RightDockWidgetArea, navigator_.get());
                navigator_->hide();
                navigator_->loadState();
                // Release pointer if destroyed by Qt before module is destroyed
                QObject::connect(navigator_.get(), &QObject::destroyed,
                                 [this](QObject*) { navigator_.release(); });
                navigator_->setVisible(true);

                menu->insertAction(action, navigator_->toggleViewAction());
                menu->removeAction(action);
            });
        }
    }

    // register widgets
    registerTrackWidgetQt<PropertyTrackWidgetQt>();
    registerTrackWidgetQt<ControlTrackWidgetQt>();

    registerSequenceEditor<PropertySequenceEditor>();
    registerSequenceEditor<ControlSequenceEditor>();

    // Map Ordinal properties
    using Types = std::tuple<float, vec2, vec3, vec4, mat2, mat3, mat4, double, dvec2, dvec3, dvec4,
                             dmat2, dmat3, dmat4, int, ivec2, ivec3, ivec4, unsigned int, uvec2,
                             uvec3, uvec4, size_t, size2_t, size3_t, size4_t>;
    util::for_each_type<Types>{}(Reghelper<OrdinalProperty>{}, *this);
    util::for_each_type<Types>{}(Reghelper<OrdinalRefProperty>{}, *this);

    util::for_each_type<std::tuple<float, double, int, unsigned int, size_t>>{}(
        Reghelper<MinMaxProperty>{}, *this);

    util::for_each_type<std::tuple<float, double, int, unsigned int, size_t, std::string>>{}(
        Reghelper<TemplateOptionProperty>{}, *this);

    util::for_each_type<std::tuple<BoolProperty, FileProperty, StringProperty>>{}(
        PropertyValueKeyframeReghelper{}, *this);

    registerPropertyTrackHelper<CameraProperty, CameraKeyframe>(*this);

    registerTrackToWidgetMap(ButtonTrack::classIdentifier(),
                             PropertyTrackWidgetQt::classIdentifier());

    registerTrackToWidgetMap(CallbackTrack::classIdentifier(),
                             PropertyTrackWidgetQt::classIdentifier());

    registerTrackToWidgetMap(ControlTrack::classIdentifier(),
                             ControlTrackWidgetQt::classIdentifier());

    registerTrackToSequenceEditorMap(ControlTrack::classIdentifier(),
                                     ControlSequenceEditor::classIdentifier());
}

AnimationQtModule::~AnimationQtModule() {
    // Unregister everything from the factory since this module _owns_ the factory. This is
    // neccessary even though the base class destructor, i.e. animation::AnimationQtSupplier, takes
    // care of this. Otherwise the supplier will unregister the items _after_ the factory is
    // destroyed.
    //
    // Other modules do not have to do this!
    unRegisterAll();
}

animation::TrackWidgetQtFactory& AnimationQtModule::getTrackWidgetQtFactory() {
    return trackWidgetQtFactory_;
}
const animation::TrackWidgetQtFactory& AnimationQtModule::getTrackWidgetQtFactory() const {
    return trackWidgetQtFactory_;
}

animation::SequenceEditorFactory& AnimationQtModule::getSequenceEditorFactory() {
    return sequenceEditorFactory_;
}
const animation::SequenceEditorFactory& AnimationQtModule::getSequenceEditorFactory() const {
    return sequenceEditorFactory_;
}

}  // namespace inviwo
<commit_msg>AnimationQt: minor refactoring<commit_after>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2016-2021 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include <modules/animationqt/animationqtmodule.h>
#include <inviwo/core/properties/ordinalproperty.h>
#include <inviwo/core/common/inviwoapplication.h>
#include <inviwo/core/util/raiiutils.h>

#include <modules/qtwidgets/inviwoqtutils.h>

#include <modules/animation/animationmodule.h>
#include <modules/animation/datastructures/animation.h>
#include <modules/animation/datastructures/buttontrack.h>
#include <modules/animation/datastructures/cameratrack.h>
#include <modules/animation/datastructures/callbacktrack.h>
#include <modules/animation/datastructures/controltrack.h>
#include <modules/animation/datastructures/keyframe.h>
#include <modules/animation/datastructures/propertytrack.h>
#include <modules/animation/datastructures/valuekeyframe.h>
#include <modules/animation/datastructures/track.h>
#include <modules/animation/animationcontroller.h>

#include <modules/animationqt/animationeditordockwidgetqt.h>
#include <modules/animationqt/demo/demonavigatordockwidgetqt.h>

#include <modules/animationqt/widgets/propertytrackwidgetqt.h>
#include <modules/animationqt/widgets/controltrackwidgetqt.h>

#include <modules/animationqt/sequenceeditor/propertysequenceeditor.h>
#include <modules/animationqt/sequenceeditor/controlsequenceeditor.h>

#include <inviwo/core/properties/boolproperty.h>
#include <inviwo/core/properties/buttonproperty.h>
#include <inviwo/core/properties/cameraproperty.h>
#include <inviwo/core/properties/fileproperty.h>
#include <inviwo/core/properties/minmaxproperty.h>
#include <inviwo/core/properties/optionproperty.h>
#include <inviwo/core/properties/ordinalproperty.h>
#include <inviwo/core/properties/ordinalrefproperty.h>
#include <inviwo/core/properties/stringproperty.h>

#include <warn/push>
#include <warn/ignore/all>
#include <QMenu>
#include <QMainWindow>
#include <QMenuBar>
#include <QAction>
#include <warn/pop>

#ifndef INVIWO_ALL_DYN_LINK
struct InitQtAnimationResources {
    // Needed for loading of resources when building statically
    // see https://wiki.qt.io/QtResources#Q_INIT_RESOURCE
    InitQtAnimationResources() { Q_INIT_RESOURCE(animation); }
    ~InitQtAnimationResources() { Q_CLEANUP_RESOURCE(animation); }
} initQtAnimationResources;
#endif

namespace inviwo {

namespace {

template <typename PropertyType, typename Keyframe,
          typename KeyframeSequence = animation::KeyframeSequenceTyped<Keyframe>>
void registerPropertyTrackHelper(animation::AnimationQtSupplier& as) {
    using namespace animation;

    using TrackType = PropertyTrack<PropertyType, Keyframe, KeyframeSequence>;

    as.registerTrackToWidgetMap(TrackType::classIdentifier(),
                                PropertyTrackWidgetQt::classIdentifier());

    as.registerTrackToSequenceEditorMap(TrackType::classIdentifier(),
                                        PropertySequenceEditor::classIdentifier());
}

template <template <typename> class Prop>
struct Reghelper {
    template <typename T>
    auto operator()(animation::AnimationQtSupplier& as) {
        using namespace animation;
        registerPropertyTrackHelper<Prop<T>, ValueKeyframe<typename Prop<T>::value_type>>(as);
    }
};

struct PropertyValueKeyframeReghelper {
    template <typename Prop>
    auto operator()(animation::AnimationQtSupplier& as) {
        using namespace animation;
        registerPropertyTrackHelper<Prop, ValueKeyframe<typename Prop::value_type>>(as);
    }
};

}  // namespace

AnimationQtModule::AnimationQtModule(InviwoApplication* app)
    : InviwoModule(app, "AnimationQt")
    , animation::AnimationQtSupplier(*this)
    , trackWidgetQtFactory_{}
    , sequenceEditorFactory_{} {

    using namespace animation;

    if (auto win = utilqt::getApplicationMainWindow()) {
        QString animationMenuName("Animation");
        QMenu* menu = nullptr;
        // Find view menu
        auto menus = win->menuBar()->findChildren<QMenu*>();
        auto viewMenuIt = std::find_if(menus.begin(), menus.end(), [](auto& m) {
            return m->title().compare(QObject::tr("&View"), Qt::CaseInsensitive) == 0;
        });

        if (viewMenuIt != menus.end()) {
            // Add to view menu if found
            menu = (*viewMenuIt);
        } else {
            // Add new menu if not found
            // To be removed when module is destroyed
            menu_ = std::make_unique<QMenu>(animationMenuName);
            win->menuBar()->addMenu(menu_.get());
            menu = menu_.get();
            // Release pointer if destroyed by Qt before module is destroyed
            QObject::connect(menu_.get(), &QObject::destroyed, [&](QObject*) { menu_.release(); });
        }

        const auto addWidgetLazy = [&](QString name, Qt::DockWidgetArea area, auto factory) {
            auto* action = menu->addAction(name);
            action->setCheckable(true);
            QObject::connect(action, &QAction::triggered, [action, win, area, menu, factory]() {
                // The first time the callback is called we will create the widget. And then replace
                // this action with the toggleViewAction from the new widget.
                util::OnScopeExit onExit([action]() { delete action; });
                auto widget = factory();
                win->addDockWidget(area, widget);
                widget->hide();
                widget->loadState();
                widget->setVisible(true);

                menu->insertAction(action, widget->toggleViewAction());
                menu->removeAction(action);
            });
        };

        addWidgetLazy("Animation Editor", Qt::BottomDockWidgetArea, [this, app, win]() {
            auto* animationModule = app->getModuleByType<AnimationModule>();
            editor_ = std::make_unique<AnimationEditorDockWidgetQt>(
                animationModule->getWorkspaceAnimations(), animationModule->getAnimationManager(),
                "Animation Editor", getTrackWidgetQtFactory(), getSequenceEditorFactory(), win);
            // Release pointer if destroyed by Qt before module is destroyed
            QObject::connect(editor_.get(), &QObject::destroyed,
                             [this](QObject*) { editor_.release(); });
            return editor_.get();
        });

        addWidgetLazy("Demo Navigator", Qt::RightDockWidgetArea, [this, app, win]() {
            auto* animationModule = app->getModuleByType<AnimationModule>();
            auto& demoController = animationModule->getDemoController();
            navigator_ =
                std::make_unique<DemoNavigatorDockWidgetQt>(demoController, "Demo Navigator", win);
            // Release pointer if destroyed by Qt before module is destroyed
            QObject::connect(navigator_.get(), &QObject::destroyed,
                             [this](QObject*) { navigator_.release(); });
            return navigator_.get();
        });
    }

    // register widgets
    registerTrackWidgetQt<PropertyTrackWidgetQt>();
    registerTrackWidgetQt<ControlTrackWidgetQt>();

    registerSequenceEditor<PropertySequenceEditor>();
    registerSequenceEditor<ControlSequenceEditor>();

    // Map Ordinal properties
    using Types = std::tuple<float, vec2, vec3, vec4, mat2, mat3, mat4, double, dvec2, dvec3, dvec4,
                             dmat2, dmat3, dmat4, int, ivec2, ivec3, ivec4, unsigned int, uvec2,
                             uvec3, uvec4, size_t, size2_t, size3_t, size4_t>;
    util::for_each_type<Types>{}(Reghelper<OrdinalProperty>{}, *this);
    util::for_each_type<Types>{}(Reghelper<OrdinalRefProperty>{}, *this);

    util::for_each_type<std::tuple<float, double, int, unsigned int, size_t>>{}(
        Reghelper<MinMaxProperty>{}, *this);

    util::for_each_type<std::tuple<float, double, int, unsigned int, size_t, std::string>>{}(
        Reghelper<TemplateOptionProperty>{}, *this);

    util::for_each_type<std::tuple<BoolProperty, FileProperty, StringProperty>>{}(
        PropertyValueKeyframeReghelper{}, *this);

    registerPropertyTrackHelper<CameraProperty, CameraKeyframe>(*this);

    registerTrackToWidgetMap(ButtonTrack::classIdentifier(),
                             PropertyTrackWidgetQt::classIdentifier());

    registerTrackToWidgetMap(CallbackTrack::classIdentifier(),
                             PropertyTrackWidgetQt::classIdentifier());

    registerTrackToWidgetMap(ControlTrack::classIdentifier(),
                             ControlTrackWidgetQt::classIdentifier());

    registerTrackToSequenceEditorMap(ControlTrack::classIdentifier(),
                                     ControlSequenceEditor::classIdentifier());
}  // namespace inviwo

AnimationQtModule::~AnimationQtModule() {
    // Unregister everything from the factory since this module _owns_ the factory. This is
    // neccessary even though the base class destructor, i.e. animation::AnimationQtSupplier, takes
    // care of this. Otherwise the supplier will unregister the items _after_ the factory is
    // destroyed.
    //
    // Other modules do not have to do this!
    unRegisterAll();
}

animation::TrackWidgetQtFactory& AnimationQtModule::getTrackWidgetQtFactory() {
    return trackWidgetQtFactory_;
}
const animation::TrackWidgetQtFactory& AnimationQtModule::getTrackWidgetQtFactory() const {
    return trackWidgetQtFactory_;
}

animation::SequenceEditorFactory& AnimationQtModule::getSequenceEditorFactory() {
    return sequenceEditorFactory_;
}
const animation::SequenceEditorFactory& AnimationQtModule::getSequenceEditorFactory() const {
    return sequenceEditorFactory_;
}

}  // namespace inviwo
<|endoftext|>


<commit_before>/*
 * FakeESOut.cpp
 *****************************************************************************
 * Copyright © 2014-2015 VideoLAN and VLC Authors
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "FakeESOut.hpp"
#include "FakeESOutID.hpp"
#include "CommandsQueue.hpp"
#include <vlc_es_out.h>
#include <vlc_block.h>
#include <cassert>

using namespace adaptive;

FakeESOut::FakeESOut( es_out_t *es, CommandsQueue *queue )
{
    real_es_out = es;
    fakeesout = new es_out_t;

    fakeesout->pf_add = esOutAdd_Callback;
    fakeesout->pf_control = esOutControl_Callback;
    fakeesout->pf_del = esOutDel_Callback;
    fakeesout->pf_destroy = esOutDestroy_Callback;
    fakeesout->pf_send = esOutSend_Callback;
    fakeesout->p_sys = (es_out_sys_t*) this;

    commandsqueue = queue;

    timestamps_offset = 0;
    extrainfo = NULL;
    vlc_mutex_init(&lock);
}

es_out_t * FakeESOut::getEsOut()
{
    return fakeesout;
}

FakeESOut::~FakeESOut()
{
    recycleAll();
    gc();

    delete fakeesout;
    vlc_mutex_destroy(&lock);
}

void FakeESOut::setTimestampOffset(mtime_t offset)
{
    vlc_mutex_lock(&lock);
    timestamps_offset = offset;
    vlc_mutex_unlock(&lock);
}

void FakeESOut::setExtraInfoProvider( ExtraFMTInfoInterface *extra )
{
    vlc_mutex_lock(&lock);
    extrainfo = extra;
    vlc_mutex_unlock(&lock);
}

FakeESOutID * FakeESOut::createNewID( const es_format_t *p_fmt )
{
    es_format_t fmtcopy;
    es_format_Init( &fmtcopy, 0, 0 );
    es_format_Copy( &fmtcopy, p_fmt );
    fmtcopy.i_group = 0; /* Always ignore group for adaptive */
    fmtcopy.i_id = -1;

    vlc_mutex_lock(&lock);

    if( extrainfo )
        extrainfo->fillExtraFMTInfo( &fmtcopy );

    FakeESOutID *es_id = new (std::nothrow) FakeESOutID( this, &fmtcopy );
    if(likely(es_id))
        fakeesidlist.push_back( es_id );

    vlc_mutex_unlock(&lock);

    es_format_Clean( &fmtcopy );

    return es_id;
}

void FakeESOut::createOrRecycleRealEsID( FakeESOutID *es_id )
{
    std::list<FakeESOutID *>::iterator it;
    es_out_id_t *realid = NULL;

    vlc_mutex_lock(&lock);

    bool b_select = false;
    for( it=recycle_candidates.begin(); it!=recycle_candidates.end(); ++it )
    {
        FakeESOutID *cand = *it;
        if ( cand->isCompatible( es_id ) )
        {
            realid = cand->realESID();
            cand->setRealESID( NULL );
            delete *it;
            recycle_candidates.erase( it );
            break;
        }
        else if( cand->getFmt()->i_cat == es_id->getFmt()->i_cat && cand->realESID() )
        {
            /* We need to enforce same selection when not reused
               Otherwise the es will select any other compatible track
               and will end this in a activate/select loop when reactivating a track */
            es_out_Control( real_es_out, ES_OUT_GET_ES_STATE, cand->realESID(), &b_select );
            break;
        }
    }

    if( !realid )
    {
        realid = es_out_Add( real_es_out, es_id->getFmt() );
        if( b_select )
            es_out_Control( real_es_out, ES_OUT_SET_ES_STATE, realid, b_select );
    }

    es_id->setRealESID( realid );

    vlc_mutex_unlock(&lock);
}

mtime_t FakeESOut::getTimestampOffset() const
{
    vlc_mutex_lock(const_cast<vlc_mutex_t *>(&lock));
    mtime_t time = timestamps_offset;
    vlc_mutex_unlock(const_cast<vlc_mutex_t *>(&lock));
    return time;
}

size_t FakeESOut::esCount() const
{
    size_t i_count = 0;
    std::list<FakeESOutID *>::const_iterator it;
    vlc_mutex_lock(const_cast<vlc_mutex_t *>(&lock));
    for( it=fakeesidlist.begin(); it!=fakeesidlist.end(); ++it )
        if( (*it)->realESID() )
            i_count++;
    vlc_mutex_unlock(const_cast<vlc_mutex_t *>(&lock));
    return i_count;
}

void FakeESOut::schedulePCRReset()
{
    AbstractCommand *command = commandsqueue->factory()->creatEsOutControlResetPCRCommand();
    if( likely(command) )
        commandsqueue->Schedule( command );
}

void FakeESOut::scheduleAllForDeletion()
{
    std::list<FakeESOutID *>::const_iterator it;
    vlc_mutex_lock(&lock);
    for( it=fakeesidlist.begin(); it!=fakeesidlist.end(); ++it )
    {
        FakeESOutID *es_id = *it;
        if(!es_id->scheduledForDeletion())
        {
            AbstractCommand *command = commandsqueue->factory()->createEsOutDelCommand( es_id );
            if( likely(command) )
            {
                commandsqueue->Schedule( command );
                es_id->setScheduledForDeletion();
            }
        }
    }
    vlc_mutex_unlock(&lock);
}

void FakeESOut::recycleAll()
{
    /* Only used when demux is killed and commands queue is cancelled */
    commandsqueue->Abort( true );
    assert(commandsqueue->isEmpty());
    vlc_mutex_lock(&lock);
    recycle_candidates.splice( recycle_candidates.end(), fakeesidlist );
    vlc_mutex_unlock(&lock);
}

void FakeESOut::gc()
{
    vlc_mutex_lock(&lock);
    if( recycle_candidates.empty() )
    {
        vlc_mutex_unlock(&lock);
        return;
    }

    std::list<FakeESOutID *>::iterator it;
    for( it=recycle_candidates.begin(); it!=recycle_candidates.end(); ++it )
    {
        if( (*it)->realESID() )
        {
            es_out_Control( real_es_out, ES_OUT_SET_ES_STATE, (*it)->realESID(), false );
            es_out_Del( real_es_out, (*it)->realESID() );
        }
        delete *it;
    }
    recycle_candidates.clear();
    vlc_mutex_unlock(&lock);
}

bool FakeESOut::hasSelectedEs() const
{
    bool b_selected = false;
    std::list<FakeESOutID *>::const_iterator it;
    vlc_mutex_lock(const_cast<vlc_mutex_t *>(&lock));
    for( it=fakeesidlist.begin(); it!=fakeesidlist.end() && !b_selected; ++it )
    {
        FakeESOutID *esID = *it;
        if( esID->realESID() )
            es_out_Control( real_es_out, ES_OUT_GET_ES_STATE, esID->realESID(), &b_selected );
    }
    vlc_mutex_unlock(const_cast<vlc_mutex_t *>(&lock));
    return b_selected;
}

bool FakeESOut::drain()
{
    bool b_drained = true;
    std::list<FakeESOutID *>::const_iterator it;
    vlc_mutex_lock(&lock);
    for( it=fakeesidlist.begin(); it!=fakeesidlist.end(); ++it )
    {
        FakeESOutID *esID = *it;
        if( esID->realESID() )
        {
            bool b_empty;
            es_out_Control( real_es_out, ES_OUT_GET_EMPTY, &b_empty );
            b_drained &= b_empty;
        }
    }
    vlc_mutex_unlock(&lock);
    return b_drained;
}

bool FakeESOut::restarting() const
{
    vlc_mutex_lock(const_cast<vlc_mutex_t *>(&lock));
    bool b = !recycle_candidates.empty();
    vlc_mutex_unlock(const_cast<vlc_mutex_t *>(&lock));
    return b;
}

void FakeESOut::recycle( FakeESOutID *id )
{
    vlc_mutex_lock(&lock);
    fakeesidlist.remove( id );
    recycle_candidates.push_back( id );
    vlc_mutex_unlock(&lock);
}

/* Static callbacks */
/* Always pass Fake ES ID to slave demuxes, it is just an opaque struct to them */
es_out_id_t * FakeESOut::esOutAdd_Callback(es_out_t *fakees, const es_format_t *p_fmt)
{
    FakeESOut *me = (FakeESOut *) fakees->p_sys;
    /* Feed the slave demux/stream_Demux with FakeESOutID struct,
     * we'll create real ES later on main demux on execution */
    FakeESOutID *es_id = me->createNewID( p_fmt );
    if( likely(es_id) )
    {
        assert(!es_id->scheduledForDeletion());
        AbstractCommand *command = me->commandsqueue->factory()->createEsOutAddCommand( es_id );
        if( likely(command) )
        {
            me->commandsqueue->Schedule( command );
            return reinterpret_cast<es_out_id_t *>(es_id);
        }
        else
        {
            delete es_id;
        }
    }
    return NULL;
}

int FakeESOut::esOutSend_Callback(es_out_t *fakees, es_out_id_t *p_es, block_t *p_block)
{
    FakeESOut *me = (FakeESOut *) fakees->p_sys;
    FakeESOutID *es_id = reinterpret_cast<FakeESOutID *>( p_es );
    assert(!es_id->scheduledForDeletion());
    mtime_t offset = me->getTimestampOffset();
    if( p_block->i_dts > VLC_TS_INVALID )
    {
        p_block->i_dts += offset;
        if( p_block->i_pts > VLC_TS_INVALID )
                p_block->i_pts += offset;
    }
    AbstractCommand *command = me->commandsqueue->factory()->createEsOutSendCommand( es_id, p_block );
    if( likely(command) )
    {
        me->commandsqueue->Schedule( command );
        return VLC_SUCCESS;
    }
    return VLC_EGENERIC;
}

void FakeESOut::esOutDel_Callback(es_out_t *fakees, es_out_id_t *p_es)
{
    FakeESOut *me = (FakeESOut *) fakees->p_sys;
    FakeESOutID *es_id = reinterpret_cast<FakeESOutID *>( p_es );
    AbstractCommand *command = me->commandsqueue->factory()->createEsOutDelCommand( es_id );
    if( likely(command) )
    {
        es_id->setScheduledForDeletion();
        me->commandsqueue->Schedule( command );
    }
}

int FakeESOut::esOutControl_Callback(es_out_t *fakees, int i_query, va_list args)
{
    FakeESOut *me = (FakeESOut *) fakees->p_sys;

    switch( i_query )
    {
        case ES_OUT_SET_PCR:
        case ES_OUT_SET_GROUP_PCR:
        {
            int i_group;
            if( i_query == ES_OUT_SET_GROUP_PCR )
                i_group = static_cast<int>(va_arg( args, int ));
            else
                i_group = 0;
            int64_t  pcr = static_cast<int64_t>(va_arg( args, int64_t ));
            pcr += me->getTimestampOffset();
            AbstractCommand *command = me->commandsqueue->factory()->createEsOutControlPCRCommand( i_group, pcr );
            if( likely(command) )
            {
                me->commandsqueue->Schedule( command );
                return VLC_SUCCESS;
            }
        }
        break;

        /* For others, we don't have the delorean, so always lie */
        case ES_OUT_GET_ES_STATE:
        {
            static_cast<void*>(va_arg( args, es_out_id_t * ));
            bool *pb = static_cast<bool *>(va_arg( args, bool * ));
            *pb = true;
            // ft
        }
        case ES_OUT_SET_ES:
        case ES_OUT_SET_ES_DEFAULT:
        case ES_OUT_SET_ES_STATE:
            return VLC_SUCCESS;

    }

    return VLC_EGENERIC;
}

void FakeESOut::esOutDestroy_Callback(es_out_t *fakees)
{
    FakeESOut *me = (FakeESOut *) fakees->p_sys;
    AbstractCommand *command = me->commandsqueue->factory()->createEsOutDestroyCommand();
    if( likely(command) )
        me->commandsqueue->Schedule( command );
}
/* !Static callbacks */
<commit_msg>demux: adaptive: reject UNKNOWN_ES<commit_after>/*
 * FakeESOut.cpp
 *****************************************************************************
 * Copyright © 2014-2015 VideoLAN and VLC Authors
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "FakeESOut.hpp"
#include "FakeESOutID.hpp"
#include "CommandsQueue.hpp"
#include <vlc_es_out.h>
#include <vlc_block.h>
#include <cassert>

using namespace adaptive;

FakeESOut::FakeESOut( es_out_t *es, CommandsQueue *queue )
{
    real_es_out = es;
    fakeesout = new es_out_t;

    fakeesout->pf_add = esOutAdd_Callback;
    fakeesout->pf_control = esOutControl_Callback;
    fakeesout->pf_del = esOutDel_Callback;
    fakeesout->pf_destroy = esOutDestroy_Callback;
    fakeesout->pf_send = esOutSend_Callback;
    fakeesout->p_sys = (es_out_sys_t*) this;

    commandsqueue = queue;

    timestamps_offset = 0;
    extrainfo = NULL;
    vlc_mutex_init(&lock);
}

es_out_t * FakeESOut::getEsOut()
{
    return fakeesout;
}

FakeESOut::~FakeESOut()
{
    recycleAll();
    gc();

    delete fakeesout;
    vlc_mutex_destroy(&lock);
}

void FakeESOut::setTimestampOffset(mtime_t offset)
{
    vlc_mutex_lock(&lock);
    timestamps_offset = offset;
    vlc_mutex_unlock(&lock);
}

void FakeESOut::setExtraInfoProvider( ExtraFMTInfoInterface *extra )
{
    vlc_mutex_lock(&lock);
    extrainfo = extra;
    vlc_mutex_unlock(&lock);
}

FakeESOutID * FakeESOut::createNewID( const es_format_t *p_fmt )
{
    es_format_t fmtcopy;
    es_format_Init( &fmtcopy, 0, 0 );
    es_format_Copy( &fmtcopy, p_fmt );
    fmtcopy.i_group = 0; /* Always ignore group for adaptive */
    fmtcopy.i_id = -1;

    vlc_mutex_lock(&lock);

    if( extrainfo )
        extrainfo->fillExtraFMTInfo( &fmtcopy );

    FakeESOutID *es_id = new (std::nothrow) FakeESOutID( this, &fmtcopy );
    if(likely(es_id))
        fakeesidlist.push_back( es_id );

    vlc_mutex_unlock(&lock);

    es_format_Clean( &fmtcopy );

    return es_id;
}

void FakeESOut::createOrRecycleRealEsID( FakeESOutID *es_id )
{
    std::list<FakeESOutID *>::iterator it;
    es_out_id_t *realid = NULL;

    vlc_mutex_lock(&lock);

    bool b_select = false;
    for( it=recycle_candidates.begin(); it!=recycle_candidates.end(); ++it )
    {
        FakeESOutID *cand = *it;
        if ( cand->isCompatible( es_id ) )
        {
            realid = cand->realESID();
            cand->setRealESID( NULL );
            delete *it;
            recycle_candidates.erase( it );
            break;
        }
        else if( cand->getFmt()->i_cat == es_id->getFmt()->i_cat && cand->realESID() )
        {
            /* We need to enforce same selection when not reused
               Otherwise the es will select any other compatible track
               and will end this in a activate/select loop when reactivating a track */
            es_out_Control( real_es_out, ES_OUT_GET_ES_STATE, cand->realESID(), &b_select );
            break;
        }
    }

    if( !realid )
    {
        realid = es_out_Add( real_es_out, es_id->getFmt() );
        if( b_select )
            es_out_Control( real_es_out, ES_OUT_SET_ES_STATE, realid, b_select );
    }

    es_id->setRealESID( realid );

    vlc_mutex_unlock(&lock);
}

mtime_t FakeESOut::getTimestampOffset() const
{
    vlc_mutex_lock(const_cast<vlc_mutex_t *>(&lock));
    mtime_t time = timestamps_offset;
    vlc_mutex_unlock(const_cast<vlc_mutex_t *>(&lock));
    return time;
}

size_t FakeESOut::esCount() const
{
    size_t i_count = 0;
    std::list<FakeESOutID *>::const_iterator it;
    vlc_mutex_lock(const_cast<vlc_mutex_t *>(&lock));
    for( it=fakeesidlist.begin(); it!=fakeesidlist.end(); ++it )
        if( (*it)->realESID() )
            i_count++;
    vlc_mutex_unlock(const_cast<vlc_mutex_t *>(&lock));
    return i_count;
}

void FakeESOut::schedulePCRReset()
{
    AbstractCommand *command = commandsqueue->factory()->creatEsOutControlResetPCRCommand();
    if( likely(command) )
        commandsqueue->Schedule( command );
}

void FakeESOut::scheduleAllForDeletion()
{
    std::list<FakeESOutID *>::const_iterator it;
    vlc_mutex_lock(&lock);
    for( it=fakeesidlist.begin(); it!=fakeesidlist.end(); ++it )
    {
        FakeESOutID *es_id = *it;
        if(!es_id->scheduledForDeletion())
        {
            AbstractCommand *command = commandsqueue->factory()->createEsOutDelCommand( es_id );
            if( likely(command) )
            {
                commandsqueue->Schedule( command );
                es_id->setScheduledForDeletion();
            }
        }
    }
    vlc_mutex_unlock(&lock);
}

void FakeESOut::recycleAll()
{
    /* Only used when demux is killed and commands queue is cancelled */
    commandsqueue->Abort( true );
    assert(commandsqueue->isEmpty());
    vlc_mutex_lock(&lock);
    recycle_candidates.splice( recycle_candidates.end(), fakeesidlist );
    vlc_mutex_unlock(&lock);
}

void FakeESOut::gc()
{
    vlc_mutex_lock(&lock);
    if( recycle_candidates.empty() )
    {
        vlc_mutex_unlock(&lock);
        return;
    }

    std::list<FakeESOutID *>::iterator it;
    for( it=recycle_candidates.begin(); it!=recycle_candidates.end(); ++it )
    {
        if( (*it)->realESID() )
        {
            es_out_Control( real_es_out, ES_OUT_SET_ES_STATE, (*it)->realESID(), false );
            es_out_Del( real_es_out, (*it)->realESID() );
        }
        delete *it;
    }
    recycle_candidates.clear();
    vlc_mutex_unlock(&lock);
}

bool FakeESOut::hasSelectedEs() const
{
    bool b_selected = false;
    std::list<FakeESOutID *>::const_iterator it;
    vlc_mutex_lock(const_cast<vlc_mutex_t *>(&lock));
    for( it=fakeesidlist.begin(); it!=fakeesidlist.end() && !b_selected; ++it )
    {
        FakeESOutID *esID = *it;
        if( esID->realESID() )
            es_out_Control( real_es_out, ES_OUT_GET_ES_STATE, esID->realESID(), &b_selected );
    }
    vlc_mutex_unlock(const_cast<vlc_mutex_t *>(&lock));
    return b_selected;
}

bool FakeESOut::drain()
{
    bool b_drained = true;
    std::list<FakeESOutID *>::const_iterator it;
    vlc_mutex_lock(&lock);
    for( it=fakeesidlist.begin(); it!=fakeesidlist.end(); ++it )
    {
        FakeESOutID *esID = *it;
        if( esID->realESID() )
        {
            bool b_empty;
            es_out_Control( real_es_out, ES_OUT_GET_EMPTY, &b_empty );
            b_drained &= b_empty;
        }
    }
    vlc_mutex_unlock(&lock);
    return b_drained;
}

bool FakeESOut::restarting() const
{
    vlc_mutex_lock(const_cast<vlc_mutex_t *>(&lock));
    bool b = !recycle_candidates.empty();
    vlc_mutex_unlock(const_cast<vlc_mutex_t *>(&lock));
    return b;
}

void FakeESOut::recycle( FakeESOutID *id )
{
    vlc_mutex_lock(&lock);
    fakeesidlist.remove( id );
    recycle_candidates.push_back( id );
    vlc_mutex_unlock(&lock);
}

/* Static callbacks */
/* Always pass Fake ES ID to slave demuxes, it is just an opaque struct to them */
es_out_id_t * FakeESOut::esOutAdd_Callback(es_out_t *fakees, const es_format_t *p_fmt)
{
    FakeESOut *me = (FakeESOut *) fakees->p_sys;

    if( p_fmt->i_cat != VIDEO_ES && p_fmt->i_cat != AUDIO_ES && p_fmt->i_cat != SPU_ES )
        return NULL;

    /* Feed the slave demux/stream_Demux with FakeESOutID struct,
     * we'll create real ES later on main demux on execution */
    FakeESOutID *es_id = me->createNewID( p_fmt );
    if( likely(es_id) )
    {
        assert(!es_id->scheduledForDeletion());
        AbstractCommand *command = me->commandsqueue->factory()->createEsOutAddCommand( es_id );
        if( likely(command) )
        {
            me->commandsqueue->Schedule( command );
            return reinterpret_cast<es_out_id_t *>(es_id);
        }
        else
        {
            delete es_id;
        }
    }
    return NULL;
}

int FakeESOut::esOutSend_Callback(es_out_t *fakees, es_out_id_t *p_es, block_t *p_block)
{
    FakeESOut *me = (FakeESOut *) fakees->p_sys;
    FakeESOutID *es_id = reinterpret_cast<FakeESOutID *>( p_es );
    assert(!es_id->scheduledForDeletion());
    mtime_t offset = me->getTimestampOffset();
    if( p_block->i_dts > VLC_TS_INVALID )
    {
        p_block->i_dts += offset;
        if( p_block->i_pts > VLC_TS_INVALID )
                p_block->i_pts += offset;
    }
    AbstractCommand *command = me->commandsqueue->factory()->createEsOutSendCommand( es_id, p_block );
    if( likely(command) )
    {
        me->commandsqueue->Schedule( command );
        return VLC_SUCCESS;
    }
    return VLC_EGENERIC;
}

void FakeESOut::esOutDel_Callback(es_out_t *fakees, es_out_id_t *p_es)
{
    FakeESOut *me = (FakeESOut *) fakees->p_sys;
    FakeESOutID *es_id = reinterpret_cast<FakeESOutID *>( p_es );
    AbstractCommand *command = me->commandsqueue->factory()->createEsOutDelCommand( es_id );
    if( likely(command) )
    {
        es_id->setScheduledForDeletion();
        me->commandsqueue->Schedule( command );
    }
}

int FakeESOut::esOutControl_Callback(es_out_t *fakees, int i_query, va_list args)
{
    FakeESOut *me = (FakeESOut *) fakees->p_sys;

    switch( i_query )
    {
        case ES_OUT_SET_PCR:
        case ES_OUT_SET_GROUP_PCR:
        {
            int i_group;
            if( i_query == ES_OUT_SET_GROUP_PCR )
                i_group = static_cast<int>(va_arg( args, int ));
            else
                i_group = 0;
            int64_t  pcr = static_cast<int64_t>(va_arg( args, int64_t ));
            pcr += me->getTimestampOffset();
            AbstractCommand *command = me->commandsqueue->factory()->createEsOutControlPCRCommand( i_group, pcr );
            if( likely(command) )
            {
                me->commandsqueue->Schedule( command );
                return VLC_SUCCESS;
            }
        }
        break;

        /* For others, we don't have the delorean, so always lie */
        case ES_OUT_GET_ES_STATE:
        {
            static_cast<void*>(va_arg( args, es_out_id_t * ));
            bool *pb = static_cast<bool *>(va_arg( args, bool * ));
            *pb = true;
            // ft
        }
        case ES_OUT_SET_ES:
        case ES_OUT_SET_ES_DEFAULT:
        case ES_OUT_SET_ES_STATE:
            return VLC_SUCCESS;

    }

    return VLC_EGENERIC;
}

void FakeESOut::esOutDestroy_Callback(es_out_t *fakees)
{
    FakeESOut *me = (FakeESOut *) fakees->p_sys;
    AbstractCommand *command = me->commandsqueue->factory()->createEsOutDestroyCommand();
    if( likely(command) )
        me->commandsqueue->Schedule( command );
}
/* !Static callbacks */
<|endoftext|>


<commit_before>/*
 * examples/smithvalence.C
 * Copyright (c) Linbox
 * ========LICENCE========
 * This file is part of the library LinBox.
 *
 * LinBox is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 */

/**\file examples/smithvalence.C
 * @example  examples/smithvalence.C
 \brief Valence of sparse matrix over Z or Zp.
 \ingroup examples
*/
#ifndef DISABLE_COMMENTATOR
#define DISABLE_COMMENTATOR
#endif

#include <linbox/linbox-config.h>

#include <iostream>
#include <fflas-ffpack/paladin/parallel.h>
#include <linbox/algorithms/smith-form-valence.h>
#include <vector>

using namespace LinBox;

int main (int argc, char **argv)
{
        //     commentator().setMaxDetailLevel (-1);
        //     commentator().setMaxDepth (-1);
        //     commentator().setReportStream (std::cerr);

	if (argc < 2 || argc > 4) {
		std::cerr << "Usage: smithvalence <matrix-file-in-supported-format> [-ata|-aat|valence] [coprime]" << std::endl;
        std::cerr << "       Optional parameters valence and coprime are integers." << std::endl;
        std::cerr << "       Prime factors of valence will be used for local computation." << std::endl;
        std::cerr << "       coprime will be used for overall rank computation." << std::endl;
		return -1;
	}

	std::ifstream input (argv[1]);
	if (!input) { std::cerr << "Error opening matrix file " << argv[1] << std::endl; return -1; }

	Givaro::ZRing<Integer> ZZ;
	MatrixStream< Givaro::ZRing<Integer> > ms( ZZ, input );
	typedef SparseMatrix<Givaro::ZRing<Integer>>  Blackbox;
	Blackbox A (ms);
	input.close();

	std::cout << "A is " << A.rowdim() << " by " << A.coldim() << std::endl;

	Givaro::ZRing<Integer>::Element val_A;

	LinBox::Timer chrono; chrono.start();
	if (argc >= 3) {
		Transpose<Blackbox> T(&A);
		if (strcmp(argv[2],"-ata") == 0) {
			Compose< Transpose<Blackbox>, Blackbox > C (&T, &A);
			std::cout << "A^T A is " << C.rowdim() << " by " << C.coldim() << std::endl;
			valence(val_A, C);
		}
		else if (strcmp(argv[2],"-aat") == 0) {
			Compose< Blackbox, Transpose<Blackbox> > C (&A, &T);
			std::cout << "A A^T is " << C.rowdim() << " by " << C.coldim() << std::endl;
			valence(val_A, C);
		}
		else {
			std::cout << "Suppose primes are contained in " << argv[2] << std::endl;
			val_A = LinBox::Integer(argv[2]);
		}
	}
	else {
		if (A.rowdim() != A.coldim()) {
			std::cerr << "Valence works only on square matrices, try either to change the dimension in the matrix file, or to compute the valence of A A^T or A^T A, via the -aat or -ata options."  << std::endl;
			exit(0);
		}
		else
			valence (val_A, A);
	}

	std::cout << "Valence is " << val_A << std::endl;

	std::vector<Givaro::Integer> Moduli;
	std::vector<size_t> exponents;
	Givaro::IntFactorDom<> FTD;

	std::vector< PairIntRk > smith;

    Givaro::Integer coprimeV=2;
	if (argc >= 4) {
		coprimeV =Givaro::Integer(argv[3]);
	}
	while ( gcd(val_A,coprimeV) > 1 ) {
		FTD.nextprimein(coprimeV);
	}

	if (argc >= 4) {
		std::cout << "Suppose " << argv[3] << " is coprime with Smith form" << std::endl;
	}

std::cout << "Some factors (50000 factoring loop bound): ";
	FTD.set(Moduli, exponents, val_A, 50000);
	std::vector<size_t>::const_iterator eit=exponents.begin();
	for(std::vector<Givaro::Integer>::const_iterator mit=Moduli.begin();
	    mit != Moduli.end(); ++mit,++eit)
		std::cout << *mit << '^' << *eit << ' ';
	std::cout << std::endl;
    smith.resize(Moduli.size());

    size_t coprimeR;

	std::cout << "num procs: " << omp_get_num_procs() << std::endl;
	std::cout << "num threads: " << NUM_THREADS << std::endl;
	std::cout << "max threads: " << MAX_THREADS << std::endl;

#pragma omp parallel
    {
#pragma omp single
        {
            for(size_t j=0; j<Moduli.size(); ++j) {
                smith[j].first = Moduli[j];
#pragma omp task shared(smith,argv) firstprivate(j)
                LRank(smith[j].second, argv[1], smith[j].first);
            }
            LRank(coprimeR, argv[1], coprimeV);
        }
	}

    std::vector<Givaro::Integer> SmithDiagonal(coprimeR,Givaro::Integer(1));

#pragma omp parallel for shared(SmithDiagonal, smith, exponents)
	for(size_t j=0; j<Moduli.size(); ++j) {

        if (smith[j].second != coprimeR) {
            std::vector<size_t> ranks;
            const PairIntRk& smithj(smith[j]);
            const size_t& exponentsj(exponents[j]);

            AllPowersRanks(ranks, smithj, exponentsj, coprimeR, argv[1]);

#pragma omp critical
            {
                populateSmithForm(SmithDiagonal, ranks, smithj, coprimeR);
            }
        }
    }

//     std::vector<size_t> * AllRanks = new std::vector<size_t>[Moduli.size()];

//     SYNCH_GROUP(
//         for(size_t j=0; j<Moduli.size(); ++j)
//     {
//         if (smith[j].second != coprimeR) {
//             std::vector<size_t>& ranks(AllRanks[j]);
//             const PairIntRk& smithj(smith[j]);
//             const size_t& exponentsj(exponents[j]);
//             { TASK(MODE(CONSTREFERENCE(smithj, exponentsj, coprimeR) WRITE(AllRanks[j])),
//             {
//                 AllPowersRanks(AllRanks[j], smithj, exponentsj, coprimeR, argv[1]);
//             })}

//         }
//     }
//         );

//     for(size_t j=0; j<Moduli.size(); ++j) {
//         if (smith[j].second != coprimeR) {
//             populateSmithForm(SmithDiagonal, AllRanks[j], smith[j], coprimeR);
//         }
//     }

//     SYNCH_GROUP(
//         FORBLOCK1D(iter, Moduli.size(), SPLITTER(),
//                    TASK(MODE(
//                        CONSTREFERENCE(SmithDiagonal, smith, exponents, coprimeR) ),
//                    {
//                         for(size_t j=iter.begin(); j != iter.end(); ++j) {
//         if (smith[j].second != coprimeR) {
//             std::vector<size_t> ranks;
//             AllPowersRanks(ranks, smith[j], exponents[j], coprimeR, argv[1]);

// #pragma omp critical
//             {

//                 populateSmithForm(SmithDiagonal, ranks, smith[j], coprimeR);
//             }
//         }
// 	}
//                         })
//                    );
//         );

	chrono.stop();

    Givaro::Integer si=1;
	size_t num=0;
	std::cerr << "Integer Smith Form :" << std::endl;
    std::cout << '(';
	for( std::vector<Givaro::Integer>::const_iterator dit=SmithDiagonal.begin();
	     dit != SmithDiagonal.end(); ++dit) {
		if (*dit == si) ++num;
		else {
			std::cerr << '[' << si << ',' << num << "] ";
			num=1;
			si = *dit;
		}
	}
	std::cerr << '[' << si << ',' << num << "] ";
	num = std::min(A.rowdim(),A.coldim()) - SmithDiagonal.size();
	si = ZZ.zero;
	if (num > 0) std::cout << '[' << si << ',' << num << ']';
	std::cout << ')' << std::endl;
	std::cerr << chrono << std::endl;

	return 0;
}

// Local Variables:
// mode: C++
// tab-width: 4
// indent-tabs-mode: nil
// c-basic-offset: 4
// End:
// vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
<commit_msg>parblock<commit_after>/*
 * examples/smithvalence.C
 * Copyright (c) Linbox
 * ========LICENCE========
 * This file is part of the library LinBox.
 *
 * LinBox is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 */

/**\file examples/smithvalence.C
 * @example  examples/smithvalence.C
 \brief Valence of sparse matrix over Z or Zp.
 \ingroup examples
*/
#ifndef DISABLE_COMMENTATOR
#define DISABLE_COMMENTATOR
#endif

#include <linbox/linbox-config.h>

#include <iostream>
#include <fflas-ffpack/paladin/parallel.h>
#include <linbox/algorithms/smith-form-valence.h>
#include <vector>

using namespace LinBox;

int main (int argc, char **argv)
{
        //     commentator().setMaxDetailLevel (-1);
        //     commentator().setMaxDepth (-1);
        //     commentator().setReportStream (std::cerr);

	if (argc < 2 || argc > 4) {
		std::cerr << "Usage: smithvalence <matrix-file-in-supported-format> [-ata|-aat|valence] [coprime]" << std::endl;
        std::cerr << "       Optional parameters valence and coprime are integers." << std::endl;
        std::cerr << "       Prime factors of valence will be used for local computation." << std::endl;
        std::cerr << "       coprime will be used for overall rank computation." << std::endl;
		return -1;
	}

	std::ifstream input (argv[1]);
	if (!input) { std::cerr << "Error opening matrix file " << argv[1] << std::endl; return -1; }

	Givaro::ZRing<Integer> ZZ;
	MatrixStream< Givaro::ZRing<Integer> > ms( ZZ, input );
	typedef SparseMatrix<Givaro::ZRing<Integer>>  Blackbox;
	Blackbox A (ms);
	input.close();

	std::cout << "A is " << A.rowdim() << " by " << A.coldim() << std::endl;

	Givaro::ZRing<Integer>::Element val_A;

	LinBox::Timer chrono; chrono.start();
	if (argc >= 3) {
		Transpose<Blackbox> T(&A);
		if (strcmp(argv[2],"-ata") == 0) {
			Compose< Transpose<Blackbox>, Blackbox > C (&T, &A);
			std::cout << "A^T A is " << C.rowdim() << " by " << C.coldim() << std::endl;
			valence(val_A, C);
		}
		else if (strcmp(argv[2],"-aat") == 0) {
			Compose< Blackbox, Transpose<Blackbox> > C (&A, &T);
			std::cout << "A A^T is " << C.rowdim() << " by " << C.coldim() << std::endl;
			valence(val_A, C);
		}
		else {
			std::cout << "Suppose primes are contained in " << argv[2] << std::endl;
			val_A = LinBox::Integer(argv[2]);
		}
	}
	else {
		if (A.rowdim() != A.coldim()) {
			std::cerr << "Valence works only on square matrices, try either to change the dimension in the matrix file, or to compute the valence of A A^T or A^T A, via the -aat or -ata options."  << std::endl;
			exit(0);
		}
		else
			valence (val_A, A);
	}

	std::cout << "Valence is " << val_A << std::endl;

	std::vector<Givaro::Integer> Moduli;
	std::vector<size_t> exponents;
	Givaro::IntFactorDom<> FTD;

	std::vector< PairIntRk > smith;

    Givaro::Integer coprimeV=2;
	if (argc >= 4) {
		coprimeV =Givaro::Integer(argv[3]);
	}
	while ( gcd(val_A,coprimeV) > 1 ) {
		FTD.nextprimein(coprimeV);
	}

	if (argc >= 4) {
		std::cout << "Suppose " << argv[3] << " is coprime with Smith form" << std::endl;
	}

std::cout << "Some factors (50000 factoring loop bound): ";
	FTD.set(Moduli, exponents, val_A, 50000);
	std::vector<size_t>::const_iterator eit=exponents.begin();
	for(std::vector<Givaro::Integer>::const_iterator mit=Moduli.begin();
	    mit != Moduli.end(); ++mit,++eit)
		std::cout << *mit << '^' << *eit << ' ';
	std::cout << std::endl;
    smith.resize(Moduli.size());

    size_t coprimeR;

	std::cout << "num procs: " << omp_get_num_procs() << std::endl;
	std::cout << "num threads: " << NUM_THREADS << std::endl;
	std::cout << "max threads: " << MAX_THREADS << std::endl;

#pragma omp parallel
    {
#pragma omp single
        {
            for(size_t j=0; j<Moduli.size(); ++j) {
                smith[j].first = Moduli[j];
#pragma omp task shared(smith,argv) firstprivate(j)
                LRank(smith[j].second, argv[1], smith[j].first);
            }
            LRank(coprimeR, argv[1], coprimeV);
        }
	}

    std::vector<Givaro::Integer> SmithDiagonal(coprimeR,Givaro::Integer(1));

// #pragma omp parallel for shared(SmithDiagonal, smith, exponents)
// 	for(size_t j=0; j<Moduli.size(); ++j) {

//         if (smith[j].second != coprimeR) {
//             std::vector<size_t> ranks;
//             const PairIntRk& smithj(smith[j]);
//             const size_t& exponentsj(exponents[j]);

//             AllPowersRanks(ranks, smithj, exponentsj, coprimeR, argv[1]);

// #pragma omp critical
//             {
//                 populateSmithForm(SmithDiagonal, ranks, smithj, coprimeR);
//             }
//         }
//     }

//     std::vector<size_t> * AllRanks = new std::vector<size_t>[Moduli.size()];

// #pragma omp parallel
//     {
//         for(size_t j=0; j<Moduli.size(); ++j) {

//             if (smith[j].second != coprimeR) {
// //                 std::vector<size_t>& ranksj(AllRanks[j]);
//                 const PairIntRk& smithj(smith[j]);
//                 const size_t& exponentsj(exponents[j]);
// #pragma omp task depend(out: AllRanks[j]) shared(smithj, exponentsj, coprimeR)
//                 {
//                     AllPowersRanks(AllRanks[j], smithj, exponentsj, coprimeR, argv[1]);
//                 }
//             }
//         }
//     }

//     for(size_t j=0; j<Moduli.size(); ++j) {
//         if (smith[j].second != coprimeR) {
//             populateSmithForm(SmithDiagonal, AllRanks[j], smith[j], coprimeR);
//         }
//     }

    std::vector<size_t> * AllRanks = new std::vector<size_t>[Moduli.size()];
    PAR_BLOCK {
        for(size_t j=0; j<Moduli.size(); ++j) {
            if (smith[j].second != coprimeR) {
//             std::vector<size_t>& ranks(AllRanks[j]);
                const PairIntRk& smithj(smith[j]);
                const size_t& exponentsj(exponents[j]);
                { TASK(MODE(CONSTREFERENCE(smithj, exponentsj, coprimeR) WRITE(AllRanks[j])),
                {
                    AllPowersRanks(AllRanks[j], smithj, exponentsj, coprimeR, argv[1]);
                })}
            }
        }
    }

    for(size_t j=0; j<Moduli.size(); ++j) {
        if (smith[j].second != coprimeR) {
            populateSmithForm(SmithDiagonal, AllRanks[j], smith[j], coprimeR);
        }
    }

    delete [] AllRanks;

//     SYNCH_GROUP(
//         FORBLOCK1D(iter, Moduli.size(), SPLITTER(),
//                    TASK(MODE(
//                        CONSTREFERENCE(SmithDiagonal, smith, exponents, coprimeR) ),
//                    {
//                         for(size_t j=iter.begin(); j != iter.end(); ++j) {
//         if (smith[j].second != coprimeR) {
//             std::vector<size_t> ranks;
//             AllPowersRanks(ranks, smith[j], exponents[j], coprimeR, argv[1]);

// #pragma omp critical
//             {

//                 populateSmithForm(SmithDiagonal, ranks, smith[j], coprimeR);
//             }
//         }
// 	}
//                         })
//                    );
//         );

	chrono.stop();

    Givaro::Integer si=1;
	size_t num=0;
	std::cerr << "Integer Smith Form :" << std::endl;
    std::cout << '(';
	for( std::vector<Givaro::Integer>::const_iterator dit=SmithDiagonal.begin();
	     dit != SmithDiagonal.end(); ++dit) {
		if (*dit == si) ++num;
		else {
			std::cerr << '[' << si << ',' << num << "] ";
			num=1;
			si = *dit;
		}
	}
	std::cerr << '[' << si << ',' << num << "] ";
	num = std::min(A.rowdim(),A.coldim()) - SmithDiagonal.size();
	si = ZZ.zero;
	if (num > 0) std::cout << '[' << si << ',' << num << ']';
	std::cout << ')' << std::endl;
	std::cerr << chrono << std::endl;

	return 0;
}

// Local Variables:
// mode: C++
// tab-width: 4
// indent-tabs-mode: nil
// c-basic-offset: 4
// End:
// vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
<|endoftext|>