<commit_before>#include "ROM.h"
#include <fstream>
#include <iostream>
#include <iterator>
#include <stdexcept>
#include <cstring>

// From https://stackoverflow.com/questions/15138353/reading-the-binary-file-into-the-vector-of-unsigned-chars
ROM ROM::FromFile(const std::string& filename) {
	// Make file stream
	std::ifstream file(filename, std::ios::binary);
	if (!file.good()) {
		throw std::runtime_error("Bad Stream Status: does the file exist?");
	}
	file.unsetf(std::ios::skipws);

	// Get file size
	std::streampos fileSize;
	file.seekg(0, std::ios::end);
	fileSize = file.tellg();
	file.seekg(0, std::ios::beg);

	std::vector<uint8_t> bytes;
	bytes.reserve(fileSize);
	bytes.insert(bytes.begin(), std::istream_iterator<uint8_t>(file), std::istream_iterator<uint8_t>());

	return ROM(bytes);
}

ROM::ROM(const std::vector<uint8_t>& bytes) {
	// Get header bytes from buffer
	const int headerSize = sizeof(ROMHeader);
	uint8_t headerBytes[headerSize];
	std::copy(bytes.begin() + 0x100, bytes.begin() + 0x100 + headerSize, headerBytes);

	memcpy(&header, headerBytes, headerSize);

	// Create ROM MBC (Memory Bank Controller) from type
	switch (header.Type) {
	case ROM_ONLY:
	case ROM_RAM:
	case ROM_R_B:
		controller = new NoMBC(header.Type);
		break;
	case ROM_MBC1:
	case ROM_MBC1_RAM:
	case ROM_MBC1_R_B:
		controller = new MBC1(header.Type);
		break;
	case ROM_MBC3:
	case ROM_MBC3_RAM:
	case ROM_MBC3_R_B:
		controller = new MBC3(header.Type);
		break;
	default:
		throw std::logic_error("Unsupported MBC type");
	}

	// Load content to ROM banks
	controller->LoadROM(header, bytes);

	//TODO load from .sav to RAM

	// The title can be either 15 or 13 characters, depending on target console
	std::string title;
	if (header.GBC.colorFlag == GBSupported || header.GBC.colorFlag == GBCOnly) {
		title = std::string(header.GBC.title);
	} else {
		title = std::string(header.GBTitle);
	}

	std::cout << "Loaded ROM: " << title << std::endl;
}

ROM::~ROM() {
	delete controller;
}

void ROM::debugPrintData() const {
	std::cout << "== ROM INFO ==" << std::endl;
	// The title can be either 15 or 13 characters, depending on target console
	if (header.GBC.colorFlag == GBSupported || header.GBC.colorFlag == GBCOnly) {
		std::cout << "Title (GBC format): " << std::string(header.GBC.title) << std::endl;
		std::cout << "Manufacturer Code: " << std::string(header.GBC.manCode) << std::endl;
	} else {
		std::cout << "Title (GB format): " << std::string(header.GBTitle) << std::endl;
	}

	// GBC features support
	std::string gbFlag = "GBC not supported";
	if (header.GBC.colorFlag == GBSupported) gbFlag = "GBC features supported";
	if (header.GBC.colorFlag == GBCOnly) gbFlag = "GBC Only";
	std::cout << "GBC support: " << gbFlag << std::endl;

	// SGB features support
	std::string super = "SGB not supported";
	if (header.superFlag == SGB) super = "SGB features supported";
	std::cout << "SGB support: " << super << std::endl;

	// ROM/RAM types
	std::cout << "ROM Type: " << std::hex << header.Type << std::endl;
	std::cout << "ROM Size: " << std::hex << header.ROMSize << std::endl;
	std::cout << "RAM Size: " << std::hex << header.RAMSize << std::endl;

	// Manufacturer code(s)
	if (header.oldLicenseeCode != 0x33) {
		std::cout << "Licensee code (old): " << std::hex << (int) header.oldLicenseeCode << std::endl;
	} else {
		std::cout << "Licensee code (new): " << header.newLicenseeCode[0] << header.newLicenseeCode[1] << std::endl;
	}

	// Destination code and other infos
	std::cout << "Destination code: " << (header.destinationCode == Japanese ? "Japan Only" : "Non-Japanese") << std::endl;
	std::cout << "Mask ROM version: " << (int) header.maskROMVersion << std::endl;

	std::cout << "== END ROM INFO ==" << std::endl;
}
<commit_msg>Add more readable informations in the ROM info subcommand<commit_after>#include "ROM.h"
#include <fstream>
#include <iostream>
#include <iterator>
#include <stdexcept>
#include <cstring>
#include <map>

// From https://stackoverflow.com/questions/15138353/reading-the-binary-file-into-the-vector-of-unsigned-chars
ROM ROM::FromFile(const std::string& filename) {
	// Make file stream
	std::ifstream file(filename, std::ios::binary);
	if (!file.good()) {
		throw std::runtime_error("Bad Stream Status: does the file exist?");
	}
	file.unsetf(std::ios::skipws);

	// Get file size
	std::streampos fileSize;
	file.seekg(0, std::ios::end);
	fileSize = file.tellg();
	file.seekg(0, std::ios::beg);

	std::vector<uint8_t> bytes;
	bytes.reserve(fileSize);
	bytes.insert(bytes.begin(), std::istream_iterator<uint8_t>(file), std::istream_iterator<uint8_t>());

	return ROM(bytes);
}

ROM::ROM(const std::vector<uint8_t>& bytes) {
	// Get header bytes from buffer
	const int headerSize = sizeof(ROMHeader);
	uint8_t headerBytes[headerSize];
	std::copy(bytes.begin() + 0x100, bytes.begin() + 0x100 + headerSize, headerBytes);

	memcpy(&header, headerBytes, headerSize);

	// Create ROM MBC (Memory Bank Controller) from type
	switch (header.Type) {
	case ROM_ONLY:
	case ROM_RAM:
	case ROM_R_B:
		controller = new NoMBC(header.Type);
		break;
	case ROM_MBC1:
	case ROM_MBC1_RAM:
	case ROM_MBC1_R_B:
		controller = new MBC1(header.Type);
		break;
	case ROM_MBC3:
	case ROM_MBC3_RAM:
	case ROM_MBC3_R_B:
		controller = new MBC3(header.Type);
		break;
	default:
		throw std::logic_error("Unsupported MBC type");
	}

	// Load content to ROM banks
	controller->LoadROM(header, bytes);

	//TODO load from .sav to RAM

	// The title can be either 15 or 13 characters, depending on target console
	std::string title;
	if (header.GBC.colorFlag == GBSupported || header.GBC.colorFlag == GBCOnly) {
		title = std::string(header.GBC.title);
	} else {
		title = std::string(header.GBTitle);
	}

	std::cout << "Loaded ROM: " << title << std::endl;
}

ROM::~ROM() {
	delete controller;
}

void ROM::debugPrintData() const {
	static const std::map<uint8_t, std::string> RomType = {
		{0x00, "ROM only"},
		{0x08, "ROM + RAM"},
		{0x09, "ROM + RAM + Battery"},
		{0x01, "ROM + MBC1"},
		{0x02, "ROM + MBC1 + RAM"},
		{0x03, "ROM + MBC1 + RAM + Battery"},
		{0x05, "ROM + MBC2"},
		{0x06, "ROM + MBC2 + RAM + Battery"},
		{0x11, "ROM + MBC3"},
		{0x12, "ROM + MBC3 + RAM"},
		{0x13, "ROM + MBC3 + RAM + Battery"},
		{0x0f, "ROM + MBC3 + Timer + Battery"},
		{0x10, "ROM + MBC3 + Timer + RAM + Battery"},
		{0x19, "ROM + MBC5"},
		{0x1a, "ROM + MBC5 + RAM"},
		{0x1b, "ROM + MBC5 + RAM + Battery"},
		{0x1c, "ROM + MBC5 + Rumble"},
		{0x1d, "ROM + MBC5 + RAM + Rumble"},
		{0x1e, "ROM + MBC5 + RAM + Rumble + Battery"},
		{0x20, "ROM + MBC6 + RAM + Battery"},
		{0x22, "ROM + MBC7 + RAM + Battery + Accelerometer"},
		{0x0b, "ROM + MMM1"},
		{0x0c, "ROM + MMM1 + RAM"},
		{0x0d, "ROM + MMM1 + RAM + Battery"},
		{0xfc, "ROM + Camera"},
		{0xfd, "ROM + TAMA5"},
		{0xfe, "ROM + HUC3"},
		{0xff, "ROM + HUC1 + RAM + Battery"}
	};

	static const std::string RomSize[] = {
		"32 kB, 2 banks",
		"64 kB, 4 banks",
		"128 kB, 8 banks",
		"256 kB, 16 banks",
		"512 kB, 32 banks",
		"1 MB, 64 banks",
		"2 MB, 128 banks",
		"4 MB, 256 banks",
		"8 MB, 512 banks"
	};

	static const std::string RamSize[] = {
		"None",
		"2 kB, 1 bank",
		"8 kB, 1 bank",
		"32 kB, 4 banks",
		"128 kB, 16 banks",
		"64 kB, 8 banks"
	};

	std::cout << "== ROM INFO ==" << std::endl;
	// The title can be either 15 or 13 characters, depending on target console
	if (header.GBC.colorFlag == GBSupported || header.GBC.colorFlag == GBCOnly) {
		std::cout << "Title (GBC format): " << std::string(header.GBC.title) << std::endl;
		std::cout << "Manufacturer Code: " << std::string(header.GBC.manCode) << std::endl;
	} else {
		std::cout << "Title (GB format): " << std::string(header.GBTitle) << std::endl;
	}

	// GBC features support
	std::string gbFlag = "GBC not supported";
	if (header.GBC.colorFlag == GBSupported) gbFlag = "GBC features supported";
	if (header.GBC.colorFlag == GBCOnly) gbFlag = "GBC Only";
	std::cout << "GBC support: " << gbFlag << std::endl;

	// SGB features support
	std::string super = "SGB not supported";
	if (header.superFlag == SGB) super = "SGB features supported";
	std::cout << "SGB support: " << super << std::endl;

	// ROM/RAM types
	std::cout << "ROM Type: " << RomType.at(header.Type) << " (" << std::hex << (int)header.Type << ")" << std::endl;
	std::cout << "ROM Size: " << RomSize[(int)header.ROMSize] << " (" << std::hex << (int)header.ROMSize << ")" << std::endl;
	std::cout << "RAM Size: " << RamSize[(int)header.RAMSize] << " (" << std::hex << (int)header.RAMSize << ")" << std::endl;

	// Manufacturer code(s)
	if (header.oldLicenseeCode != 0x33) {
		std::cout << "Licensee code (old): " << std::hex << (int) header.oldLicenseeCode << std::endl;
	} else {
		std::cout << "Licensee code (new): " << header.newLicenseeCode[0] << header.newLicenseeCode[1] << std::endl;
	}

	// Destination code and other infos
	std::cout << "Destination code: " << (header.destinationCode == Japanese ? "Japan Only" : "Non-Japanese") << std::endl;
	std::cout << "Mask ROM version: " << (int) header.maskROMVersion << std::endl;

	std::cout << "== END ROM INFO ==" << std::endl;
}
<|endoftext|>


<commit_before>/*
 * This file is part of the µOS++ distribution.
 *   (https://github.com/micro-os-plus)
 * Copyright (c) 2016 Liviu Ionescu.
 *
 * µOS++ 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, version 3.
 *
 * µOS++ 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, see <http://www.gnu.org/licenses/>.
 */

#include <cmsis-plus/std/thread>
#include <cmsis-plus/diag/trace.h>

#include <cstdio>
#include <iostream>

using namespace os::cmsis;

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"

// ----------------------------------------------------------------------------

void
task1 (void);

void
task2 (const void* args);

void
task3 (void* args);

// ----------------------------------------------------------------------------

void
task1 (void)
{
  trace::printf ("task1()\n");
  ;
}

void
task2 (const void* args)
{
  trace::printf ("task2(%p)\n", args);
}

void
task3 (void* args)
{
  trace::printf ("task3(%p)\n", args);
}

// ----------------------------------------------------------------------------

extern "C" void
sleep_for_ticks (uint32_t);

void
sleep_for_ticks (uint32_t)
{

}

// ----------------------------------------------------------------------------

int
main (int argc, char* argv[])
{
  using namespace ::std::chrono;
  using namespace os::cmsis::std;
  using namespace os::cmsis;

  char c;
  thread th11
    { task1 };

  th11.native_handle ()->__run_function ();

  new int ();

  thread th12
    { "th12", 777, task1 };

  th12.native_handle ()->__run_function ();

  thread th13
    { (char*) "th12", 777, task1 };

  th13.native_handle ()->__run_function ();

  thread th21
    { task2, &c };

  th21.native_handle ()->__run_function ();

  thread th31
    { task3, &c };

  th31.native_handle ()->__run_function ();

  this_thread::sleep_for (milliseconds
    { 20 });

  th11.native_handle ()->set_priority (rtos::Priority::high);

  th11.join ();
  th12.join ();
  th13.join ();
  th21.join ();
  th31.join ();

  trace::printf ("%s done.\n", argv[0]);
  return 0;
}

#pragma GCC diagnostic pop
<commit_msg>update std test for chrono<commit_after>/*
 * This file is part of the µOS++ distribution.
 *   (https://github.com/micro-os-plus)
 * Copyright (c) 2016 Liviu Ionescu.
 *
 * µOS++ 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, version 3.
 *
 * µOS++ 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, see <http://www.gnu.org/licenses/>.
 */

#include <cmsis-plus/std/thread>
#include <cmsis-plus/diag/trace.h>

#include <cstdio>
#include <iostream>
#include <chrono>

using namespace os::cmsis;

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"

// ----------------------------------------------------------------------------

void
task1 (void);

void
task2 (const void* args);

void
task3 (void* args);

// ----------------------------------------------------------------------------

void
task1 (void)
{
  trace::printf ("task1()\n");
}

void
task2 (const void* args)
{
  trace::printf ("task2(%p)\n", args);
}

void
task3 (void* args)
{
  trace::printf ("task3(%p)\n", args);
}

// ----------------------------------------------------------------------------

extern "C" void
sleep_for_ticks (uint32_t);

void
sleep_for_ticks (uint32_t)
{

}

// ----------------------------------------------------------------------------

#if !defined(OS_INCLUDE_CMSIS_THREAD_VARIADICS)
#error OS_INCLUDE_CMSIS_THREAD_VARIADICS
#endif

int
main (int argc, char* argv[])
{
  using namespace ::std::chrono;
  using namespace os::cmsis::std;
  using namespace os::cmsis;
  using namespace os;

  char c;
  thread th11
    { task1 };

  th11.native_handle ()->__run_function ();

  new int ();

  thread th12
    { new rtos::Thread
      { "th12", 777, rtos::Priority::normal, task1 } };

  th12.native_handle ()->__run_function ();

  thread th13
    { new rtos::Thread
      { (char*) "th13", 777, rtos::Priority::normal, task1 } };

  th13.native_handle ()->__run_function ();

#if 1

  thread th21
    { task2, &c };

  th21.native_handle ()->__run_function ();

  thread th31
    { task3, &c };

  th31.native_handle ()->__run_function ();

  this_thread::sleep_for (microseconds (3001001));
  this_thread::sleep_for (milliseconds (3001));
  this_thread::sleep_for (seconds (3));

#if 0
  int n = 70;
  this_thread::sleep_for (milliseconds (n));
#endif

  th11.native_handle ()->set_priority (rtos::Priority::high);

  th11.join ();
  th12.join ();
  th13.join ();
  th21.join ();
  th31.join ();
#endif

  trace::printf ("%s done.\n", argv[0]);
  return 0;
}

#pragma GCC diagnostic pop
<|endoftext|>


<commit_before>#include "Units.h"
#include "RhoZ.h"
using namespace GeFiCa;

void RhoZ::DoSOR2(int idx)
{
   if (fIsFixed[idx])return;
   // 2nd-order Successive Over-Relaxation
   double density=fImpurity[idx]*Qe;
   double drm=fdC1m[idx]; // dr_minus
   double drp=fdC1p[idx];
   double dzm=fdC2m[idx];
   double dzp=fdC2p[idx];
   double pzm,pzp,prm,prp; // pzm: potential_z_plus
   if(idx>=fN1)pzm=fV[idx-fN1];
   else pzm=fV[idx+fN1];
   if(idx>=fN-fN1)pzp=fV[idx];
   else pzp=fV[idx+fN1];
   if(idx%fN1==0)prm=fV[idx];
   else prm=fV[idx-1];
   if(idx%fN1==fN1-1)prp=fV[idx];
   else prp=fV[idx+1];
   double tmp=(density/epsilon
         + 1/fC1[idx]*(prp-prm)/(drm+drp) +(prp/drp+prm/drm)*2/(drm+drp)
         + (pzp/dzp+pzm/dzm)*2/(dzp+dzm))/
      ((1/drm+1/drp)*2/(drm+drp)+(1/dzp+1/dzm)*2/(dzp+dzm));
   //find minmium and maxnium of all five grid, the new one should not go overthem.
   //find min
   double min=prm;
   double max=prm;
   if(min>prp)min=prp;
   if (min>pzp)min=pzp;
   if (min>pzm)min=pzm;

   //find max
   if(max<prp)max=prp;
   if (max<pzp)max=pzp;
   if (max<pzm)max=pzm;
//if tmp is greater or smaller than max and min, set tmp to it.

      //over relax
   //fV[idx]=Csor*(tmp-fV[idx])+fV[idx];
   //if need calculate depleted voltage
   double oldP=fV[idx];
   tmp=Csor*(tmp-oldP)+oldP;
   if(tmp<min) {
      fV[idx]=min;
      fIsDepleted[idx]=false;
   } else if(tmp>max) {
      fV[idx]=max;
      fIsDepleted[idx]=false;
   } else
      fIsDepleted[idx]=true;

   if(fIsDepleted[idx]||V0==V1) fV[idx]=tmp;
}
//_____________________________________________________________________________
//
double RhoZ::GetC()
{
   Info("GetC", "Start...");
   CalculatePotential(GeFiCa::kSOR2); // identify undepleted region
   // set impurity to zero
   double *tmpImpurity=fImpurity;
   for (int i=0;i<fN;i++) {
      if (fImpurity[i]!=0) {
         //impurity not clear,return
         //return -1;
         fImpurity=new double[fN];
         for (int j=0;j<fN;j++) {
            fImpurity[j]=0;
            if (!fIsFixed[j] && !fIsDepleted[j]) fIsFixed[j]=true;
         }
         break;
      }
   }
   // calculate potential without impurity
   Nsor=0; CalculatePotential(GeFiCa::kSOR2);
   // set impurity back
   if(fImpurity!=tmpImpurity) delete []fImpurity;
   fImpurity=tmpImpurity;

   // calculate C based on CV^2/2 = epsilon int E^2 dx^3 / 2
   double dV=V0-V1; if(dV<0)dV=-dV;
   double SumofElectricField=0;
   for(int i=0;i<fN;i++) {
      double e1=fE1[i];
      double e2=fE2[i];
      double dr=fdC1p[i];
      double dz=fdC2p[i];
      SumofElectricField+=(e1*e1+e2*e2)*fC1[i]*dr*dz;
   }
   double c=SumofElectricField*2*3.14159*epsilon/dV/dV;
   Info("GetC","%.2f pF",c/pF);
   return c;
}

<commit_msg>removed Nsor<commit_after>#include "Units.h"
#include "RhoZ.h"
using namespace GeFiCa;

void RhoZ::DoSOR2(int idx)
{
   if (fIsFixed[idx])return;
   // 2nd-order Successive Over-Relaxation
   double density=fImpurity[idx]*Qe;
   double drm=fdC1m[idx]; // dr_minus
   double drp=fdC1p[idx];
   double dzm=fdC2m[idx];
   double dzp=fdC2p[idx];
   double pzm,pzp,prm,prp; // pzm: potential_z_plus
   if(idx>=fN1)pzm=fV[idx-fN1];
   else pzm=fV[idx+fN1];
   if(idx>=fN-fN1)pzp=fV[idx];
   else pzp=fV[idx+fN1];
   if(idx%fN1==0)prm=fV[idx];
   else prm=fV[idx-1];
   if(idx%fN1==fN1-1)prp=fV[idx];
   else prp=fV[idx+1];
   double tmp=(density/epsilon
         + 1/fC1[idx]*(prp-prm)/(drm+drp) +(prp/drp+prm/drm)*2/(drm+drp)
         + (pzp/dzp+pzm/dzm)*2/(dzp+dzm))/
      ((1/drm+1/drp)*2/(drm+drp)+(1/dzp+1/dzm)*2/(dzp+dzm));
   //find minmium and maxnium of all five grid, the new one should not go overthem.
   //find min
   double min=prm;
   double max=prm;
   if(min>prp)min=prp;
   if (min>pzp)min=pzp;
   if (min>pzm)min=pzm;

   //find max
   if(max<prp)max=prp;
   if (max<pzp)max=pzp;
   if (max<pzm)max=pzm;
//if tmp is greater or smaller than max and min, set tmp to it.

      //over relax
   //fV[idx]=Csor*(tmp-fV[idx])+fV[idx];
   //if need calculate depleted voltage
   double oldP=fV[idx];
   tmp=Csor*(tmp-oldP)+oldP;
   if(tmp<min) {
      fV[idx]=min;
      fIsDepleted[idx]=false;
   } else if(tmp>max) {
      fV[idx]=max;
      fIsDepleted[idx]=false;
   } else
      fIsDepleted[idx]=true;

   if(fIsDepleted[idx]||V0==V1) fV[idx]=tmp;
}
//_____________________________________________________________________________
//
double RhoZ::GetC()
{
   Info("GetC", "Start...");
   CalculatePotential(GeFiCa::kSOR2); // identify undepleted region
   // set impurity to zero
   double *tmpImpurity=fImpurity;
   for (int i=0;i<fN;i++) {
      if (fImpurity[i]!=0) {
         //impurity not clear,return
         //return -1;
         fImpurity=new double[fN];
         for (int j=0;j<fN;j++) {
            fImpurity[j]=0;
            if (!fIsFixed[j] && !fIsDepleted[j]) fIsFixed[j]=true;
         }
         break;
      }
   }
   // calculate potential without impurity
   CalculatePotential(GeFiCa::kSOR2);
   // set impurity back
   if(fImpurity!=tmpImpurity) delete []fImpurity;
   fImpurity=tmpImpurity;

   // calculate C based on CV^2/2 = epsilon int E^2 dx^3 / 2
   double dV=V0-V1; if(dV<0)dV=-dV;
   double SumofElectricField=0;
   for(int i=0;i<fN;i++) {
      double e1=fE1[i];
      double e2=fE2[i];
      double dr=fdC1p[i];
      double dz=fdC2p[i];
      SumofElectricField+=(e1*e1+e2*e2)*fC1[i]*dr*dz;
   }
   double c=SumofElectricField*2*3.14159*epsilon/dV/dV;
   Info("GetC","%.2f pF",c/pF);
   return c;
}

<|endoftext|>


<commit_before>/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
#ident "Copyright (c) 2011 Tokutek Inc.  All rights reserved."
#ident "$Id$"

#include <toku_portability.h>
#include <zlib.h>
#include <lzma.h>

#include "compress.h"
#include "memory.h"
#include "quicklz.h"
#include "toku_assert.h"

static inline enum toku_compression_method
normalize_compression_method(enum toku_compression_method method)
// Effect: resolve "friendly" names like "fast" and "small" into their real values.
{
    switch (method) {
    case TOKU_DEFAULT_COMPRESSION_METHOD:
    case TOKU_FAST_COMPRESSION_METHOD:
        return TOKU_QUICKLZ_METHOD;
    case TOKU_SMALL_COMPRESSION_METHOD:
        return TOKU_LZMA_METHOD;
    default:
        return method; // everything else is fine
    }
}

size_t toku_compress_bound (enum toku_compression_method a, size_t size)
// See compress.h for the specification of this function.
{
    a = normalize_compression_method(a);
    switch (a) {
    case TOKU_NO_COMPRESSION:
        return size + 1;
    case TOKU_LZMA_METHOD:
	return 1+lzma_stream_buffer_bound(size); // We need one extra for the rfc1950-style header byte (bits -03 are TOKU_LZMA_METHOD (1), bits 4-7 are the compression level)
    case TOKU_QUICKLZ_METHOD:
        return size+400 + 1;  // quicklz manual says 400 bytes is enough.  We need one more byte for the rfc1950-style header byte.  bits 0-3 are 9, bits 4-7 are the QLZ_COMPRESSION_LEVEL.
    case TOKU_ZLIB_METHOD:
        return compressBound (size);
    default:
        break;
    }
    // fall through for bad enum (thus compiler can warn us if we didn't use all the enums
    assert(0); return 0;
}

static const int zlib_compression_level = 5;

void toku_compress (enum toku_compression_method a,
                    // the following types and naming conventions come from zlib.h
                    Bytef       *dest,   uLongf *destLen,
                    const Bytef *source, uLong   sourceLen)
// See compress.h for the specification of this function.
{
    a = normalize_compression_method(a);
    assert(sourceLen < (1LL << 32));
    switch (a) {
    case TOKU_NO_COMPRESSION:
        dest[0] = TOKU_NO_COMPRESSION;
        memcpy(dest + 1, source, sourceLen);
        *destLen = sourceLen + 1;
        return;
    case TOKU_ZLIB_METHOD: {
        int r = compress2(dest, destLen, source, sourceLen, zlib_compression_level);
        assert(r == Z_OK);
        assert((dest[0]&0xF) == TOKU_ZLIB_METHOD);
        return;
    }
    case  TOKU_QUICKLZ_METHOD: {
        if (sourceLen==0) {
            // quicklz requires at least one byte, so we handle this ourselves
            assert(1 <= *destLen);
            *destLen = 1;
        } else {
            qlz_state_compress *XCALLOC(qsc);
            size_t actual_destlen = qlz_compress(source, (char*)(dest+1), sourceLen, qsc);
            assert(actual_destlen +1 <= *destLen);
            *destLen = actual_destlen+1; // add one for the rfc1950-style header byte.
            toku_free(qsc);
        }
        // Fill in that first byte
        dest[0] = TOKU_QUICKLZ_METHOD + (QLZ_COMPRESSION_LEVEL << 4);
        return;
    }
    case TOKU_LZMA_METHOD: {
	const int lzma_compression_level = 2;
	if (sourceLen==0) {
	    // lzma version 4.999 requires at least one byte, so we'll do it ourselves.
	    assert(1<=*destLen);
	    *destLen = 1;
	} else {
	    size_t out_pos = 1;
	    lzma_ret r = lzma_easy_buffer_encode(lzma_compression_level, LZMA_CHECK_CRC32, NULL,
						 source, sourceLen,
						 dest, &out_pos, *destLen);
	    assert(out_pos < *destLen);
            if (r != LZMA_OK) {
                fprintf(stderr, "lzma_easy_buffer_encode() returned %d\n", (int) r);
            }
	    assert(r==LZMA_OK);
	    *destLen = out_pos;
	}
	dest[0] = TOKU_LZMA_METHOD + (lzma_compression_level << 4);

	return;
    }
    default:
        break;
    }
    // default fall through to error.
    assert(0);
}

void toku_decompress (Bytef       *dest,   uLongf destLen,
                      const Bytef *source, uLongf sourceLen)
// See compress.h for the specification of this function.
{
    assert(sourceLen>=1); // need at least one byte for the RFC header.
    switch (source[0] & 0xF) {
    case TOKU_NO_COMPRESSION:
        memcpy(dest, source + 1, sourceLen - 1);
        return;
    case TOKU_ZLIB_METHOD: {
        uLongf actual_destlen = destLen;
        int r = uncompress(dest, &actual_destlen, source, sourceLen);
        assert(r == Z_OK);
        assert(actual_destlen == destLen);
        return;
    }
    case TOKU_QUICKLZ_METHOD:
        if (sourceLen>1) {
            qlz_state_decompress *XCALLOC(qsd);
            uLongf actual_destlen = qlz_decompress((char*)source+1, dest, qsd);
            assert(actual_destlen == destLen);
            toku_free(qsd);
        } else {
            // length 1 means there is no data, so do nothing.
            assert(destLen==0);
        }
        return;
    case TOKU_LZMA_METHOD: {
	if (sourceLen>1) {
	    uint64_t memlimit = UINT64_MAX;
	    size_t out_pos = 0;
	    size_t in_pos  = 1;
	    lzma_ret r = lzma_stream_buffer_decode(&memlimit,  // memlimit, use UINT64_MAX to disable this check
						   0,          // flags
						   NULL,       // allocator
						   source, &in_pos, sourceLen,
						   dest,   &out_pos, destLen);
	    assert(r==LZMA_OK);
	    assert(out_pos == destLen);
	} else {
	    // length 1 means there is no data, so do nothing.
	    assert(destLen==0);
	}
	return;
    }
    }
    // default fall through to error.
    assert(0);
}
<commit_msg>fixes #5915 disable crc for lzma<commit_after>/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
#ident "Copyright (c) 2011 Tokutek Inc.  All rights reserved."
#ident "$Id$"

#include <toku_portability.h>
#include <zlib.h>
#include <lzma.h>

#include "compress.h"
#include "memory.h"
#include "quicklz.h"
#include "toku_assert.h"

static inline enum toku_compression_method
normalize_compression_method(enum toku_compression_method method)
// Effect: resolve "friendly" names like "fast" and "small" into their real values.
{
    switch (method) {
    case TOKU_DEFAULT_COMPRESSION_METHOD:
    case TOKU_FAST_COMPRESSION_METHOD:
        return TOKU_QUICKLZ_METHOD;
    case TOKU_SMALL_COMPRESSION_METHOD:
        return TOKU_LZMA_METHOD;
    default:
        return method; // everything else is fine
    }
}

size_t toku_compress_bound (enum toku_compression_method a, size_t size)
// See compress.h for the specification of this function.
{
    a = normalize_compression_method(a);
    switch (a) {
    case TOKU_NO_COMPRESSION:
        return size + 1;
    case TOKU_LZMA_METHOD:
	return 1+lzma_stream_buffer_bound(size); // We need one extra for the rfc1950-style header byte (bits -03 are TOKU_LZMA_METHOD (1), bits 4-7 are the compression level)
    case TOKU_QUICKLZ_METHOD:
        return size+400 + 1;  // quicklz manual says 400 bytes is enough.  We need one more byte for the rfc1950-style header byte.  bits 0-3 are 9, bits 4-7 are the QLZ_COMPRESSION_LEVEL.
    case TOKU_ZLIB_METHOD:
        return compressBound (size);
    default:
        break;
    }
    // fall through for bad enum (thus compiler can warn us if we didn't use all the enums
    assert(0); return 0;
}

static const int zlib_compression_level = 5;

void toku_compress (enum toku_compression_method a,
                    // the following types and naming conventions come from zlib.h
                    Bytef       *dest,   uLongf *destLen,
                    const Bytef *source, uLong   sourceLen)
// See compress.h for the specification of this function.
{
    a = normalize_compression_method(a);
    assert(sourceLen < (1LL << 32));
    switch (a) {
    case TOKU_NO_COMPRESSION:
        dest[0] = TOKU_NO_COMPRESSION;
        memcpy(dest + 1, source, sourceLen);
        *destLen = sourceLen + 1;
        return;
    case TOKU_ZLIB_METHOD: {
        int r = compress2(dest, destLen, source, sourceLen, zlib_compression_level);
        assert(r == Z_OK);
        assert((dest[0]&0xF) == TOKU_ZLIB_METHOD);
        return;
    }
    case  TOKU_QUICKLZ_METHOD: {
        if (sourceLen==0) {
            // quicklz requires at least one byte, so we handle this ourselves
            assert(1 <= *destLen);
            *destLen = 1;
        } else {
            qlz_state_compress *XCALLOC(qsc);
            size_t actual_destlen = qlz_compress(source, (char*)(dest+1), sourceLen, qsc);
            assert(actual_destlen +1 <= *destLen);
            *destLen = actual_destlen+1; // add one for the rfc1950-style header byte.
            toku_free(qsc);
        }
        // Fill in that first byte
        dest[0] = TOKU_QUICKLZ_METHOD + (QLZ_COMPRESSION_LEVEL << 4);
        return;
    }
    case TOKU_LZMA_METHOD: {
	const int lzma_compression_level = 2;
	if (sourceLen==0) {
	    // lzma version 4.999 requires at least one byte, so we'll do it ourselves.
	    assert(1<=*destLen);
	    *destLen = 1;
	} else {
	    size_t out_pos = 1;
	    lzma_ret r = lzma_easy_buffer_encode(lzma_compression_level, LZMA_CHECK_NONE, NULL,
						 source, sourceLen,
						 dest, &out_pos, *destLen);
	    assert(out_pos < *destLen);
            if (r != LZMA_OK) {
                fprintf(stderr, "lzma_easy_buffer_encode() returned %d\n", (int) r);
            }
	    assert(r==LZMA_OK);
	    *destLen = out_pos;
	}
	dest[0] = TOKU_LZMA_METHOD + (lzma_compression_level << 4);

	return;
    }
    default:
        break;
    }
    // default fall through to error.
    assert(0);
}

void toku_decompress (Bytef       *dest,   uLongf destLen,
                      const Bytef *source, uLongf sourceLen)
// See compress.h for the specification of this function.
{
    assert(sourceLen>=1); // need at least one byte for the RFC header.
    switch (source[0] & 0xF) {
    case TOKU_NO_COMPRESSION:
        memcpy(dest, source + 1, sourceLen - 1);
        return;
    case TOKU_ZLIB_METHOD: {
        uLongf actual_destlen = destLen;
        int r = uncompress(dest, &actual_destlen, source, sourceLen);
        assert(r == Z_OK);
        assert(actual_destlen == destLen);
        return;
    }
    case TOKU_QUICKLZ_METHOD:
        if (sourceLen>1) {
            qlz_state_decompress *XCALLOC(qsd);
            uLongf actual_destlen = qlz_decompress((char*)source+1, dest, qsd);
            assert(actual_destlen == destLen);
            toku_free(qsd);
        } else {
            // length 1 means there is no data, so do nothing.
            assert(destLen==0);
        }
        return;
    case TOKU_LZMA_METHOD: {
	if (sourceLen>1) {
	    uint64_t memlimit = UINT64_MAX;
	    size_t out_pos = 0;
	    size_t in_pos  = 1;
	    lzma_ret r = lzma_stream_buffer_decode(&memlimit,  // memlimit, use UINT64_MAX to disable this check
						   0,          // flags
						   NULL,       // allocator
						   source, &in_pos, sourceLen,
						   dest,   &out_pos, destLen);
	    assert(r==LZMA_OK);
	    assert(out_pos == destLen);
	} else {
	    // length 1 means there is no data, so do nothing.
	    assert(destLen==0);
	}
	return;
    }
    }
    // default fall through to error.
    assert(0);
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 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 "media/audio/null_audio_sink.h"

#include "base/bind.h"
#include "base/stringprintf.h"
#include "base/sys_byteorder.h"
#include "base/threading/platform_thread.h"

namespace media {

NullAudioSink::NullAudioSink()
    : initialized_(false),
      playback_rate_(0.0),
      playing_(false),
      callback_(NULL),
      thread_("NullAudioThread"),
      hash_audio_for_testing_(false) {
}

void NullAudioSink::Initialize(const AudioParameters& params,
                               RenderCallback* callback) {
  DCHECK(!initialized_);
  params_ = params;

  audio_data_.reserve(params.channels());
  for (int i = 0; i < params.channels(); ++i) {
    float* channel_data = new float[params.frames_per_buffer()];
    audio_data_.push_back(channel_data);
  }

  if (hash_audio_for_testing_) {
    md5_channel_contexts_.reset(new base::MD5Context[params.channels()]);
    for (int i = 0; i < params.channels(); i++)
      base::MD5Init(&md5_channel_contexts_[i]);
  }

  callback_ = callback;
  initialized_ = true;
}

void NullAudioSink::Start() {
  if (!thread_.Start())
    return;

  thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
      &NullAudioSink::FillBufferTask, this));
}

void NullAudioSink::Stop() {
  SetPlaying(false);
  thread_.Stop();
}

void NullAudioSink::Play() {
  SetPlaying(true);
}

void NullAudioSink::Pause(bool /* flush */) {
  SetPlaying(false);
}

void NullAudioSink::SetPlaybackRate(float rate) {
  base::AutoLock auto_lock(lock_);
  playback_rate_ = rate;
}

bool NullAudioSink::SetVolume(double volume) {
  // Audio is always muted.
  return volume == 0.0;
}

void NullAudioSink::GetVolume(double* volume) {
  // Audio is always muted.
  *volume = 0.0;
}

void NullAudioSink::SetPlaying(bool is_playing) {
  base::AutoLock auto_lock(lock_);
  playing_ = is_playing;
}

NullAudioSink::~NullAudioSink() {
  DCHECK(!thread_.IsRunning());
  for (size_t i = 0; i < audio_data_.size(); ++i)
    delete [] audio_data_[i];
}

void NullAudioSink::FillBufferTask() {
  base::AutoLock auto_lock(lock_);

  base::TimeDelta delay;
  // Only consume buffers when actually playing.
  if (playing_)  {
    DCHECK_GT(playback_rate_, 0.0f);
    int requested_frames = params_.frames_per_buffer();
    int frames_received = callback_->Render(audio_data_, requested_frames, 0);
    int frames_per_millisecond =
        params_.sample_rate() / base::Time::kMillisecondsPerSecond;

    if (hash_audio_for_testing_ && frames_received > 0) {
      DCHECK_EQ(sizeof(float), sizeof(uint32));
      int channels = audio_data_.size();
      for (int channel_idx = 0; channel_idx < channels; ++channel_idx) {
        for (int frame_idx = 0; frame_idx < frames_received; frame_idx++) {
          // Convert float to uint32 w/o conversion loss.
          uint32 frame = base::ByteSwapToLE32(*reinterpret_cast<uint32*>(
              &audio_data_[channel_idx][frame_idx]));
          base::MD5Update(
              &md5_channel_contexts_[channel_idx], base::StringPiece(
                  reinterpret_cast<char*>(&frame), sizeof(frame)));
        }
      }
    }

    // Calculate our sleep duration, taking playback rate into consideration.
    delay = base::TimeDelta::FromMilliseconds(
        frames_received / (frames_per_millisecond * playback_rate_));
  } else {
    // If paused, sleep for 10 milliseconds before polling again.
    delay = base::TimeDelta::FromMilliseconds(10);
  }

  // Sleep for at least one millisecond so we don't spin the CPU.
  MessageLoop::current()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&NullAudioSink::FillBufferTask, this),
      std::max(delay, base::TimeDelta::FromMilliseconds(1)));
}

void NullAudioSink::StartAudioHashForTesting() {
  DCHECK(!initialized_);
  hash_audio_for_testing_ = true;
}

std::string NullAudioSink::GetAudioHashForTesting() {
  DCHECK(hash_audio_for_testing_);

  // If initialize failed or was never called, ensure we return an empty hash.
  if (!initialized_) {
    md5_channel_contexts_.reset(new base::MD5Context[1]);
    base::MD5Init(&md5_channel_contexts_[0]);
  }

  // Hash all channels into the first channel.
  base::MD5Digest digest;
  for (size_t i = 1; i < audio_data_.size(); i++) {
    base::MD5Final(&digest, &md5_channel_contexts_[i]);
    base::MD5Update(&md5_channel_contexts_[0], base::StringPiece(
        reinterpret_cast<char*>(&digest), sizeof(base::MD5Digest)));
  }

  base::MD5Final(&digest, &md5_channel_contexts_[0]);
  return base::MD5DigestToBase16(digest);
}

}  // namespace media
<commit_msg>Fix address casting in audio hashing.<commit_after>// Copyright (c) 2012 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 "media/audio/null_audio_sink.h"

#include "base/bind.h"
#include "base/stringprintf.h"
#include "base/sys_byteorder.h"
#include "base/threading/platform_thread.h"

namespace media {

NullAudioSink::NullAudioSink()
    : initialized_(false),
      playback_rate_(0.0),
      playing_(false),
      callback_(NULL),
      thread_("NullAudioThread"),
      hash_audio_for_testing_(false) {
}

void NullAudioSink::Initialize(const AudioParameters& params,
                               RenderCallback* callback) {
  DCHECK(!initialized_);
  params_ = params;

  audio_data_.reserve(params.channels());
  for (int i = 0; i < params.channels(); ++i) {
    float* channel_data = new float[params.frames_per_buffer()];
    audio_data_.push_back(channel_data);
  }

  if (hash_audio_for_testing_) {
    md5_channel_contexts_.reset(new base::MD5Context[params.channels()]);
    for (int i = 0; i < params.channels(); i++)
      base::MD5Init(&md5_channel_contexts_[i]);
  }

  callback_ = callback;
  initialized_ = true;
}

void NullAudioSink::Start() {
  if (!thread_.Start())
    return;

  thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
      &NullAudioSink::FillBufferTask, this));
}

void NullAudioSink::Stop() {
  SetPlaying(false);
  thread_.Stop();
}

void NullAudioSink::Play() {
  SetPlaying(true);
}

void NullAudioSink::Pause(bool /* flush */) {
  SetPlaying(false);
}

void NullAudioSink::SetPlaybackRate(float rate) {
  base::AutoLock auto_lock(lock_);
  playback_rate_ = rate;
}

bool NullAudioSink::SetVolume(double volume) {
  // Audio is always muted.
  return volume == 0.0;
}

void NullAudioSink::GetVolume(double* volume) {
  // Audio is always muted.
  *volume = 0.0;
}

void NullAudioSink::SetPlaying(bool is_playing) {
  base::AutoLock auto_lock(lock_);
  playing_ = is_playing;
}

NullAudioSink::~NullAudioSink() {
  DCHECK(!thread_.IsRunning());
  for (size_t i = 0; i < audio_data_.size(); ++i)
    delete [] audio_data_[i];
}

void NullAudioSink::FillBufferTask() {
  base::AutoLock auto_lock(lock_);

  base::TimeDelta delay;
  // Only consume buffers when actually playing.
  if (playing_)  {
    DCHECK_GT(playback_rate_, 0.0f);
    int requested_frames = params_.frames_per_buffer();
    int frames_received = callback_->Render(audio_data_, requested_frames, 0);
    int frames_per_millisecond =
        params_.sample_rate() / base::Time::kMillisecondsPerSecond;

    if (hash_audio_for_testing_ && frames_received > 0) {
      DCHECK_EQ(sizeof(float), sizeof(uint32));
      int channels = audio_data_.size();
      for (int channel_idx = 0; channel_idx < channels; ++channel_idx) {
        float* channel = audio_data_[channel_idx];
        for (int frame_idx = 0; frame_idx < frames_received; frame_idx++) {
          // Convert float to uint32 w/o conversion loss.
          uint32 frame = base::ByteSwapToLE32(
              bit_cast<uint32>(channel[frame_idx]));
          base::MD5Update(
              &md5_channel_contexts_[channel_idx], base::StringPiece(
                  reinterpret_cast<char*>(&frame), sizeof(frame)));
        }
      }
    }

    // Calculate our sleep duration, taking playback rate into consideration.
    delay = base::TimeDelta::FromMilliseconds(
        frames_received / (frames_per_millisecond * playback_rate_));
  } else {
    // If paused, sleep for 10 milliseconds before polling again.
    delay = base::TimeDelta::FromMilliseconds(10);
  }

  // Sleep for at least one millisecond so we don't spin the CPU.
  MessageLoop::current()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&NullAudioSink::FillBufferTask, this),
      std::max(delay, base::TimeDelta::FromMilliseconds(1)));
}

void NullAudioSink::StartAudioHashForTesting() {
  DCHECK(!initialized_);
  hash_audio_for_testing_ = true;
}

std::string NullAudioSink::GetAudioHashForTesting() {
  DCHECK(hash_audio_for_testing_);

  // If initialize failed or was never called, ensure we return an empty hash.
  if (!initialized_) {
    md5_channel_contexts_.reset(new base::MD5Context[1]);
    base::MD5Init(&md5_channel_contexts_[0]);
  }

  // Hash all channels into the first channel.
  base::MD5Digest digest;
  for (size_t i = 1; i < audio_data_.size(); i++) {
    base::MD5Final(&digest, &md5_channel_contexts_[i]);
    base::MD5Update(&md5_channel_contexts_[0], base::StringPiece(
        reinterpret_cast<char*>(&digest), sizeof(base::MD5Digest)));
  }

  base::MD5Final(&digest, &md5_channel_contexts_[0]);
  return base::MD5DigestToBase16(digest);
}

}  // namespace media
<|endoftext|>


<commit_before>/* Copyright 2019 The TensorFlow 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 "tensorflow/lite/tools/benchmark/benchmark_performance_options.h"

#include <algorithm>
#include <iomanip>
#include <memory>
#include <sstream>
#include <utility>

#include "tensorflow/core/util/stats_calculator.h"
#include "tensorflow/lite/c/c_api_internal.h"
#if defined(__ANDROID__)
#include "tensorflow/lite/delegates/gpu/gl_delegate.h"
#endif
#include "tensorflow/lite/profiling/time.h"
#include "tensorflow/lite/tools/benchmark/benchmark_params.h"
#include "tensorflow/lite/tools/benchmark/benchmark_utils.h"
#include "tensorflow/lite/tools/benchmark/logging.h"
#include "tensorflow/lite/tools/command_line_flags.h"

namespace tflite {
namespace benchmark {

void MultiRunStatsRecorder::OnBenchmarkStart(const BenchmarkParams& params) {
  current_run_name_.clear();

  if (params.Get<bool>("use_nnapi")) {
    current_run_name_ = "nnapi";
    return;
  }

  if (params.Get<bool>("use_gpu")) {
#if defined(__ANDROID__)
    const bool allow_precision_loss =
        params.Get<bool>("gpu_precision_loss_allowed");
    const std::string precision_tag = allow_precision_loss ? "fp16" : "fp32";
    current_run_name_ = "gpu(" + precision_tag + ")";
#else
    current_run_name_ = "gpu(fp16, fastest)-default";
#endif
    return;
  }

  // Handle cases run on CPU
  // Note: could use std::to_string to convert an integer to string but it
  // requires C++11.
  std::stringstream sstm;
  sstm << "cpu w/ " << params.Get<int32_t>("num_threads") << " threads";
  current_run_name_ = sstm.str();
}

void MultiRunStatsRecorder::OnBenchmarkEnd(const BenchmarkResults& results) {
  each_run_stats_.emplace_back(std::make_pair(current_run_name_, results));
}

void MultiRunStatsRecorder::OutputStats() {
  // Make a 80-character-long header.
  TFLITE_LOG(INFO) << "\n==============Summary of All Runs w/ Different "
                      "Performance Options==============";
  std::sort(each_run_stats_.begin(), each_run_stats_.end(),
            EachRunStatsEntryComparator());

  for (const auto& run_stats : each_run_stats_) {
    std::stringstream stream;
    // Output the name of this run first.
    stream << std::setw(26) << run_stats.first << ": ";
    run_stats.second.inference_time_us().OutputToStream(&stream);
    TFLITE_LOG(INFO) << stream.str();
  }
}

BenchmarkPerformanceOptions::BenchmarkPerformanceOptions(
    BenchmarkModel* single_option_run)
    : BenchmarkPerformanceOptions(DefaultParams(), single_option_run,
                                  DefaultRunStatsRecorder()) {}

BenchmarkPerformanceOptions::BenchmarkPerformanceOptions(
    BenchmarkParams params, BenchmarkModel* single_option_run,
    std::unique_ptr<MultiRunStatsRecorder> all_run_stats)
    : params_(std::move(params)),
      single_option_run_(single_option_run),
      single_option_run_params_(single_option_run->mutable_params()),
      all_run_stats_(std::move(all_run_stats)) {
  single_option_run_->AddListener(all_run_stats_.get());
}

BenchmarkParams BenchmarkPerformanceOptions::DefaultParams() {
  BenchmarkParams params;
  params.AddParam("perf_options_list",
                  BenchmarkParam::Create<std::string>("all"));
  params.AddParam("option_benchmark_run_delay",
                  BenchmarkParam::Create<float>(-1.0f));
  params.AddParam("random_shuffle_benchmark_runs",
                  BenchmarkParam::Create<bool>(true));
  return params;
}

std::unique_ptr<MultiRunStatsRecorder>
BenchmarkPerformanceOptions::DefaultRunStatsRecorder() {
  return std::unique_ptr<MultiRunStatsRecorder>(new MultiRunStatsRecorder());
}

std::vector<Flag> BenchmarkPerformanceOptions::GetFlags() {
  return {
      CreateFlag<std::string>(
          "perf_options_list", &params_,
          "A comma-separated list of TFLite performance options to benchmark. "
          "By default, all performance options are benchmarked."),
      CreateFlag<float>("option_benchmark_run_delay", &params_,
                        "The delay between two consecutive runs of "
                        "benchmarking performance options in seconds."),
      CreateFlag<bool>(
          "random_shuffle_benchmark_runs", &params_,
          "Whether to perform all benchmark runs, each of which has different "
          "performance options, in a random order. It is enabled by default."),
  };
}

bool BenchmarkPerformanceOptions::ParseFlags(int* argc, char** argv) {
  auto flag_list = GetFlags();
  const bool parse_result =
      Flags::Parse(argc, const_cast<const char**>(argv), flag_list);
  if (!parse_result) {
    std::string usage = Flags::Usage(argv[0], flag_list);
    TFLITE_LOG(ERROR) << usage;
    return false;
  }

  // Parse the value of --perf_options_list to find performance options to be
  // benchmarked.
  return ParsePerfOptions();
}

bool BenchmarkPerformanceOptions::ParsePerfOptions() {
  const auto& perf_options_list = params_.Get<std::string>("perf_options_list");
  if (!util::SplitAndParse(perf_options_list, ',', &perf_options_)) {
    TFLITE_LOG(ERROR) << "Cannot parse --perf_options_list: '"
                      << perf_options_list
                      << "'. Please double-check its value.";
    perf_options_.clear();
    return false;
  }

  const auto valid_options = GetValidPerfOptions();
  bool is_valid = true;
  for (const auto& option : perf_options_) {
    if (std::find(valid_options.begin(), valid_options.end(), option) ==
        valid_options.end()) {
      is_valid = false;
      break;
    }
  }
  if (!is_valid) {
    std::string valid_options_str;
    for (int i = 0; i < valid_options.size() - 1; ++i) {
      valid_options_str += (valid_options[i] + ", ");
    }
    valid_options_str += valid_options.back();
    TFLITE_LOG(ERROR)
        << "There are invalid perf options in --perf_options_list: '"
        << perf_options_list << "'. Valid perf options are: ["
        << valid_options_str << "]";
    perf_options_.clear();
    return false;
  }
  return true;
}

std::vector<std::string> BenchmarkPerformanceOptions::GetValidPerfOptions()
    const {
  return {"all", "cpu", "gpu", "nnapi"};
}

bool BenchmarkPerformanceOptions::HasOption(const std::string& option) const {
  return std::find(perf_options_.begin(), perf_options_.end(), option) !=
         perf_options_.end();
}

void BenchmarkPerformanceOptions::ResetPerformanceOptions() {
  single_option_run_params_->Set<int32_t>("num_threads", 1);
  single_option_run_params_->Set<bool>("use_gpu", false);
#if defined(__ANDROID__)
  single_option_run_params_->Set<bool>("gpu_precision_loss_allowed", true);
#endif
  single_option_run_params_->Set<bool>("use_nnapi", false);
}

void BenchmarkPerformanceOptions::CreatePerformanceOptions() {
  TFLITE_LOG(INFO) << "The list of TFLite runtime options to be benchmarked: ["
                   << params_.Get<std::string>("perf_options_list") << "]";

  const bool benchmark_all = HasOption("all");

  if (benchmark_all || HasOption("cpu")) {
    const std::vector<int> num_threads = {1, 2, 4};
    for (const int count : num_threads) {
      BenchmarkParams params;
      params.AddParam("num_threads", BenchmarkParam::Create<int32_t>(count));
      all_run_params_.emplace_back(std::move(params));
    }
  }

  if (benchmark_all || HasOption("gpu")) {
#if defined(__ANDROID__)
    const std::vector<bool> allow_precision_loss = {true, false};
    const std::vector<int32_t> gl_obj_types = {TFLITE_GL_OBJECT_TYPE_TEXTURE,
                                               TFLITE_GL_OBJECT_TYPE_BUFFER};
    for (const auto precision_loss : allow_precision_loss) {
      for (const auto obj_type : gl_obj_types) {
        BenchmarkParams params;
        params.AddParam("use_gpu", BenchmarkParam::Create<bool>(true));
        params.AddParam("gpu_precision_loss_allowed",
                        BenchmarkParam::Create<bool>(precision_loss));
        all_run_params_.emplace_back(std::move(params));
      }
    }
#endif
    // Note by default, gpu delegate allows to operate on lower precision and
    // uses the fastest GL object type.
    BenchmarkParams params;
    params.AddParam("use_gpu", BenchmarkParam::Create<bool>(true));
    all_run_params_.emplace_back(std::move(params));
  }

  if (benchmark_all || HasOption("nnapi")) {
    BenchmarkParams params;
    params.AddParam("use_nnapi", BenchmarkParam::Create<bool>(true));
    all_run_params_.emplace_back(std::move(params));
  }
}

void BenchmarkPerformanceOptions::Run(int argc, char** argv) {
  // We first parse flags for single-option runs to get information like
  // parameters of the input model etc.
  if (single_option_run_->ParseFlags(&argc, argv) != kTfLiteOk) return;

  // Now, we parse flags that are specified for this particular binary.
  if (!ParseFlags(&argc, argv)) return;

  // Now, the remaining are unrecognized flags and we simply print them out.
  for (int i = 1; i < argc; ++i) {
    TFLITE_LOG(WARN) << "WARNING: unrecognized commandline flag: " << argv[i];
  }

  CreatePerformanceOptions();

  if (params_.Get<bool>("random_shuffle_benchmark_runs")) {
    std::random_shuffle(all_run_params_.begin(), all_run_params_.end());
  }

  // Now perform all runs, each with different performance-affecting parameters.
  for (const auto& run_params : all_run_params_) {
    // Reset all performance-related options before any runs.
    ResetPerformanceOptions();
    single_option_run_params_->Set(run_params);
    util::SleepForSeconds(params_.Get<float>("option_benchmark_run_delay"));
    single_option_run_->Run();
  }

  all_run_stats_->OutputStats();
}
}  // namespace benchmark
}  // namespace tflite
<commit_msg>Change imported header file to resolve build error.<commit_after>/* Copyright 2019 The TensorFlow 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 "tensorflow/lite/tools/benchmark/benchmark_performance_options.h"

#include <algorithm>
#include <iomanip>
#include <memory>
#include <sstream>
#include <utility>

#include "tensorflow/core/util/stats_calculator.h"
#include "tensorflow/lite/c/c_api_internal.h"
#if defined(__ANDROID__)
#include "tensorflow/lite/delegates/gpu/delegate.h"
#endif
#include "tensorflow/lite/profiling/time.h"
#include "tensorflow/lite/tools/benchmark/benchmark_params.h"
#include "tensorflow/lite/tools/benchmark/benchmark_utils.h"
#include "tensorflow/lite/tools/benchmark/logging.h"
#include "tensorflow/lite/tools/command_line_flags.h"

namespace tflite {
namespace benchmark {

void MultiRunStatsRecorder::OnBenchmarkStart(const BenchmarkParams& params) {
  current_run_name_.clear();

  if (params.Get<bool>("use_nnapi")) {
    current_run_name_ = "nnapi";
    return;
  }

  if (params.Get<bool>("use_gpu")) {
#if defined(__ANDROID__)
    const bool allow_precision_loss =
        params.Get<bool>("gpu_precision_loss_allowed");
    const std::string precision_tag = allow_precision_loss ? "fp16" : "fp32";
    current_run_name_ = "gpu(" + precision_tag + ")";
#else
    current_run_name_ = "gpu(fp16, fastest)-default";
#endif
    return;
  }

  // Handle cases run on CPU
  // Note: could use std::to_string to convert an integer to string but it
  // requires C++11.
  std::stringstream sstm;
  sstm << "cpu w/ " << params.Get<int32_t>("num_threads") << " threads";
  current_run_name_ = sstm.str();
}

void MultiRunStatsRecorder::OnBenchmarkEnd(const BenchmarkResults& results) {
  each_run_stats_.emplace_back(std::make_pair(current_run_name_, results));
}

void MultiRunStatsRecorder::OutputStats() {
  // Make a 80-character-long header.
  TFLITE_LOG(INFO) << "\n==============Summary of All Runs w/ Different "
                      "Performance Options==============";
  std::sort(each_run_stats_.begin(), each_run_stats_.end(),
            EachRunStatsEntryComparator());

  for (const auto& run_stats : each_run_stats_) {
    std::stringstream stream;
    // Output the name of this run first.
    stream << std::setw(26) << run_stats.first << ": ";
    run_stats.second.inference_time_us().OutputToStream(&stream);
    TFLITE_LOG(INFO) << stream.str();
  }
}

BenchmarkPerformanceOptions::BenchmarkPerformanceOptions(
    BenchmarkModel* single_option_run)
    : BenchmarkPerformanceOptions(DefaultParams(), single_option_run,
                                  DefaultRunStatsRecorder()) {}

BenchmarkPerformanceOptions::BenchmarkPerformanceOptions(
    BenchmarkParams params, BenchmarkModel* single_option_run,
    std::unique_ptr<MultiRunStatsRecorder> all_run_stats)
    : params_(std::move(params)),
      single_option_run_(single_option_run),
      single_option_run_params_(single_option_run->mutable_params()),
      all_run_stats_(std::move(all_run_stats)) {
  single_option_run_->AddListener(all_run_stats_.get());
}

BenchmarkParams BenchmarkPerformanceOptions::DefaultParams() {
  BenchmarkParams params;
  params.AddParam("perf_options_list",
                  BenchmarkParam::Create<std::string>("all"));
  params.AddParam("option_benchmark_run_delay",
                  BenchmarkParam::Create<float>(-1.0f));
  params.AddParam("random_shuffle_benchmark_runs",
                  BenchmarkParam::Create<bool>(true));
  return params;
}

std::unique_ptr<MultiRunStatsRecorder>
BenchmarkPerformanceOptions::DefaultRunStatsRecorder() {
  return std::unique_ptr<MultiRunStatsRecorder>(new MultiRunStatsRecorder());
}

std::vector<Flag> BenchmarkPerformanceOptions::GetFlags() {
  return {
      CreateFlag<std::string>(
          "perf_options_list", &params_,
          "A comma-separated list of TFLite performance options to benchmark. "
          "By default, all performance options are benchmarked."),
      CreateFlag<float>("option_benchmark_run_delay", &params_,
                        "The delay between two consecutive runs of "
                        "benchmarking performance options in seconds."),
      CreateFlag<bool>(
          "random_shuffle_benchmark_runs", &params_,
          "Whether to perform all benchmark runs, each of which has different "
          "performance options, in a random order. It is enabled by default."),
  };
}

bool BenchmarkPerformanceOptions::ParseFlags(int* argc, char** argv) {
  auto flag_list = GetFlags();
  const bool parse_result =
      Flags::Parse(argc, const_cast<const char**>(argv), flag_list);
  if (!parse_result) {
    std::string usage = Flags::Usage(argv[0], flag_list);
    TFLITE_LOG(ERROR) << usage;
    return false;
  }

  // Parse the value of --perf_options_list to find performance options to be
  // benchmarked.
  return ParsePerfOptions();
}

bool BenchmarkPerformanceOptions::ParsePerfOptions() {
  const auto& perf_options_list = params_.Get<std::string>("perf_options_list");
  if (!util::SplitAndParse(perf_options_list, ',', &perf_options_)) {
    TFLITE_LOG(ERROR) << "Cannot parse --perf_options_list: '"
                      << perf_options_list
                      << "'. Please double-check its value.";
    perf_options_.clear();
    return false;
  }

  const auto valid_options = GetValidPerfOptions();
  bool is_valid = true;
  for (const auto& option : perf_options_) {
    if (std::find(valid_options.begin(), valid_options.end(), option) ==
        valid_options.end()) {
      is_valid = false;
      break;
    }
  }
  if (!is_valid) {
    std::string valid_options_str;
    for (int i = 0; i < valid_options.size() - 1; ++i) {
      valid_options_str += (valid_options[i] + ", ");
    }
    valid_options_str += valid_options.back();
    TFLITE_LOG(ERROR)
        << "There are invalid perf options in --perf_options_list: '"
        << perf_options_list << "'. Valid perf options are: ["
        << valid_options_str << "]";
    perf_options_.clear();
    return false;
  }
  return true;
}

std::vector<std::string> BenchmarkPerformanceOptions::GetValidPerfOptions()
    const {
  return {"all", "cpu", "gpu", "nnapi"};
}

bool BenchmarkPerformanceOptions::HasOption(const std::string& option) const {
  return std::find(perf_options_.begin(), perf_options_.end(), option) !=
         perf_options_.end();
}

void BenchmarkPerformanceOptions::ResetPerformanceOptions() {
  single_option_run_params_->Set<int32_t>("num_threads", 1);
  single_option_run_params_->Set<bool>("use_gpu", false);
#if defined(__ANDROID__)
  single_option_run_params_->Set<bool>("gpu_precision_loss_allowed", true);
#endif
  single_option_run_params_->Set<bool>("use_nnapi", false);
}

void BenchmarkPerformanceOptions::CreatePerformanceOptions() {
  TFLITE_LOG(INFO) << "The list of TFLite runtime options to be benchmarked: ["
                   << params_.Get<std::string>("perf_options_list") << "]";

  const bool benchmark_all = HasOption("all");

  if (benchmark_all || HasOption("cpu")) {
    const std::vector<int> num_threads = {1, 2, 4};
    for (const int count : num_threads) {
      BenchmarkParams params;
      params.AddParam("num_threads", BenchmarkParam::Create<int32_t>(count));
      all_run_params_.emplace_back(std::move(params));
    }
  }

  if (benchmark_all || HasOption("gpu")) {
#if defined(__ANDROID__)
    const std::vector<bool> allow_precision_loss = {true, false};
    const std::vector<int32_t> gl_obj_types = {TFLITE_GL_OBJECT_TYPE_TEXTURE,
                                               TFLITE_GL_OBJECT_TYPE_BUFFER};
    for (const auto precision_loss : allow_precision_loss) {
      for (const auto obj_type : gl_obj_types) {
        BenchmarkParams params;
        params.AddParam("use_gpu", BenchmarkParam::Create<bool>(true));
        params.AddParam("gpu_precision_loss_allowed",
                        BenchmarkParam::Create<bool>(precision_loss));
        all_run_params_.emplace_back(std::move(params));
      }
    }
#endif
    // Note by default, gpu delegate allows to operate on lower precision and
    // uses the fastest GL object type.
    BenchmarkParams params;
    params.AddParam("use_gpu", BenchmarkParam::Create<bool>(true));
    all_run_params_.emplace_back(std::move(params));
  }

  if (benchmark_all || HasOption("nnapi")) {
    BenchmarkParams params;
    params.AddParam("use_nnapi", BenchmarkParam::Create<bool>(true));
    all_run_params_.emplace_back(std::move(params));
  }
}

void BenchmarkPerformanceOptions::Run(int argc, char** argv) {
  // We first parse flags for single-option runs to get information like
  // parameters of the input model etc.
  if (single_option_run_->ParseFlags(&argc, argv) != kTfLiteOk) return;

  // Now, we parse flags that are specified for this particular binary.
  if (!ParseFlags(&argc, argv)) return;

  // Now, the remaining are unrecognized flags and we simply print them out.
  for (int i = 1; i < argc; ++i) {
    TFLITE_LOG(WARN) << "WARNING: unrecognized commandline flag: " << argv[i];
  }

  CreatePerformanceOptions();

  if (params_.Get<bool>("random_shuffle_benchmark_runs")) {
    std::random_shuffle(all_run_params_.begin(), all_run_params_.end());
  }

  // Now perform all runs, each with different performance-affecting parameters.
  for (const auto& run_params : all_run_params_) {
    // Reset all performance-related options before any runs.
    ResetPerformanceOptions();
    single_option_run_params_->Set(run_params);
    util::SleepForSeconds(params_.Get<float>("option_benchmark_run_delay"));
    single_option_run_->Run();
  }

  all_run_stats_->OutputStats();
}
}  // namespace benchmark
}  // namespace tflite
<|endoftext|>


<commit_before>// Copyright (c) 2009 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 "chrome/browser/gtk/location_bar_view_gtk.h"

#include <string>

#include "base/basictypes.h"
#include "base/gfx/gtk_util.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/alternate_nav_url_fetcher.h"
#include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h"
#include "chrome/browser/command_updater.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/gtk_util.h"
#include "chrome/common/page_transition_types.h"
#include "skia/include/SkBitmap.h"
#include "webkit/glue/window_open_disposition.h"

namespace {

// We are positioned with a little bit of extra space that we don't use now.
const int kTopMargin = 1;
const int kBottomMargin = 1;
// We don't want to edit control's text to be right against the edge.
const int kEditLeftRightPadding = 4;
// We draw a border on the top and bottom (but not on left or right).
const int kBorderThickness = 1;

// TODO(deanm): Eventually this should be painted with the background png
// image, but for now we get pretty close by just drawing a solid border.
const GdkColor kBorderColor = GDK_COLOR_RGB(0xbe, 0xc8, 0xd4);

}  // namespace

// static
const GdkColor LocationBarViewGtk::kBackgroundColorByLevel[3] = {
  GDK_COLOR_RGB(255, 245, 195),  // SecurityLevel SECURE: Yellow.
  GDK_COLOR_RGB(255, 255, 255),  // SecurityLevel NORMAL: White.
  GDK_COLOR_RGB(255, 255, 255),  // SecurityLevel INSECURE: White.
};

LocationBarViewGtk::LocationBarViewGtk(CommandUpdater* command_updater,
    ToolbarModel* toolbar_model, AutocompletePopupPositioner* popup_positioner)
    : profile_(NULL),
      command_updater_(command_updater),
      toolbar_model_(toolbar_model),
      popup_positioner_(popup_positioner),
      disposition_(CURRENT_TAB),
      transition_(PageTransition::TYPED) {
}

LocationBarViewGtk::~LocationBarViewGtk() {
  // All of our widgets should have be children of / owned by the alignment.
  alignment_.Destroy();
}

void LocationBarViewGtk::Init() {
  location_entry_.reset(new AutocompleteEditViewGtk(this,
                                                    toolbar_model_,
                                                    profile_,
                                                    command_updater_,
                                                    popup_positioner_));
  location_entry_->Init();

  alignment_.Own(gtk_alignment_new(0.0, 0.0, 1.0, 1.0));
  gtk_alignment_set_padding(GTK_ALIGNMENT(alignment_.get()),
                            kTopMargin + kBorderThickness,
                            kBottomMargin + kBorderThickness,
                            kEditLeftRightPadding, kEditLeftRightPadding);
  // We will paint for the alignment, to paint the background and border.
  gtk_widget_set_app_paintable(alignment_.get(), TRUE);
  // Have GTK double buffer around the expose signal.
  gtk_widget_set_double_buffered(alignment_.get(), TRUE);
  g_signal_connect(alignment_.get(), "expose-event",
                   G_CALLBACK(&HandleExposeThunk), this);

  gtk_container_add(GTK_CONTAINER(alignment_.get()),
                    location_entry_->widget());
}

void LocationBarViewGtk::SetProfile(Profile* profile) {
  profile_ = profile;
}

void LocationBarViewGtk::Update(const TabContents* contents) {
  location_entry_->Update(contents);
  // The security level (background color) could have changed, etc.
  gtk_widget_queue_draw(alignment_.get());
}

void LocationBarViewGtk::OnAutocompleteAccept(const GURL& url,
      WindowOpenDisposition disposition,
      PageTransition::Type transition,
      const GURL& alternate_nav_url) {
  if (!url.is_valid())
    return;

  location_input_ = UTF8ToWide(url.spec());
  disposition_ = disposition;
  transition_ = transition;

  if (!command_updater_)
    return;

  if (!alternate_nav_url.is_valid()) {
    command_updater_->ExecuteCommand(IDC_OPEN_CURRENT_URL);
    return;
  }

  scoped_ptr<AlternateNavURLFetcher> fetcher(
      new AlternateNavURLFetcher(alternate_nav_url));
  // The AlternateNavURLFetcher will listen for the pending navigation
  // notification that will be issued as a result of the "open URL." It
  // will automatically install itself into that navigation controller.
  command_updater_->ExecuteCommand(IDC_OPEN_CURRENT_URL);
  if (fetcher->state() == AlternateNavURLFetcher::NOT_STARTED) {
    // I'm not sure this should be reachable, but I'm not also sure enough
    // that it shouldn't to stick in a NOTREACHED().  In any case, this is
    // harmless; we can simply let the fetcher get deleted here and it will
    // clean itself up properly.
  } else {
    fetcher.release();  // The navigation controller will delete the fetcher.
  }
}

void LocationBarViewGtk::OnChanged() {
  // TODO(deanm): Here is where we would do layout when we have things like
  // the keyword display, ssl icons, etc.
}

void LocationBarViewGtk::OnInputInProgress(bool in_progress) {
  NOTIMPLEMENTED();
}

SkBitmap LocationBarViewGtk::GetFavIcon() const {
  NOTIMPLEMENTED();
  return SkBitmap();
}

std::wstring LocationBarViewGtk::GetTitle() const {
  NOTIMPLEMENTED();
  return std::wstring();
}

void LocationBarViewGtk::ShowFirstRunBubble() {
  NOTIMPLEMENTED();
}

std::wstring LocationBarViewGtk::GetInputString() const {
  return location_input_;
}

WindowOpenDisposition LocationBarViewGtk::GetWindowOpenDisposition() const {
  return disposition_;
}

PageTransition::Type LocationBarViewGtk::GetPageTransition() const {
  return transition_;
}

void LocationBarViewGtk::AcceptInput() {
  AcceptInputWithDisposition(CURRENT_TAB);
}

void LocationBarViewGtk::AcceptInputWithDisposition(
    WindowOpenDisposition disposition) {
  location_entry_->model()->AcceptInput(disposition, false);
}

void LocationBarViewGtk::FocusLocation() {
  location_entry_->SetFocus();
  location_entry_->SelectAll(true);
}

void LocationBarViewGtk::FocusSearch() {
  location_entry_->SetUserText(L"?");
  location_entry_->SetFocus();
}

void LocationBarViewGtk::UpdatePageActions() {
  NOTIMPLEMENTED();
}

void LocationBarViewGtk::SaveStateToContents(TabContents* contents) {
  NOTIMPLEMENTED();
}

void LocationBarViewGtk::Revert() {
  NOTIMPLEMENTED();
}

gboolean LocationBarViewGtk::HandleExpose(GtkWidget* widget,
                                          GdkEventExpose* event) {
  GdkDrawable* drawable = GDK_DRAWABLE(event->window);
  GdkGC* gc = gdk_gc_new(drawable);

  GdkRectangle* alloc_rect = &alignment_.get()->allocation;

  // The area outside of our margin, which includes the border.
  GdkRectangle inner_rect = {
      alloc_rect->x,
      alloc_rect->y + kTopMargin,
      alloc_rect->width,
      alloc_rect->height - kTopMargin - kBottomMargin};

  // Draw our 1px border.  TODO(deanm): Maybe this would be cleaner as an
  // overdrawn stroked rect with a clip to the allocation?
  gdk_gc_set_rgb_fg_color(gc, &kBorderColor);
  gdk_draw_rectangle(drawable, gc, TRUE,
                     inner_rect.x,
                     inner_rect.y,
                     inner_rect.width,
                     kBorderThickness);
  gdk_draw_rectangle(drawable, gc, TRUE,
                     inner_rect.x,
                     inner_rect.y + inner_rect.height - kBorderThickness,
                     inner_rect.width,
                     kBorderThickness);

  // Draw the background within the border.
  gdk_gc_set_rgb_fg_color(gc,
      &kBackgroundColorByLevel[toolbar_model_->GetSchemeSecurityLevel()]);
  gdk_draw_rectangle(drawable, gc, TRUE,
                     inner_rect.x,
                     inner_rect.y + kBorderThickness,
                     inner_rect.width,
                     inner_rect.height - (kBorderThickness * 2));

  g_object_unref(gc);

  return FALSE;  // Continue propagating the expose.
}
<commit_msg>Redraw the location bar on reload. This change is Gtk+ port of 100198.<commit_after>// Copyright (c) 2009 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 "chrome/browser/gtk/location_bar_view_gtk.h"

#include <string>

#include "base/basictypes.h"
#include "base/gfx/gtk_util.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/alternate_nav_url_fetcher.h"
#include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h"
#include "chrome/browser/command_updater.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/gtk_util.h"
#include "chrome/common/page_transition_types.h"
#include "skia/include/SkBitmap.h"
#include "webkit/glue/window_open_disposition.h"

namespace {

// We are positioned with a little bit of extra space that we don't use now.
const int kTopMargin = 1;
const int kBottomMargin = 1;
// We don't want to edit control's text to be right against the edge.
const int kEditLeftRightPadding = 4;
// We draw a border on the top and bottom (but not on left or right).
const int kBorderThickness = 1;

// TODO(deanm): Eventually this should be painted with the background png
// image, but for now we get pretty close by just drawing a solid border.
const GdkColor kBorderColor = GDK_COLOR_RGB(0xbe, 0xc8, 0xd4);

}  // namespace

// static
const GdkColor LocationBarViewGtk::kBackgroundColorByLevel[3] = {
  GDK_COLOR_RGB(255, 245, 195),  // SecurityLevel SECURE: Yellow.
  GDK_COLOR_RGB(255, 255, 255),  // SecurityLevel NORMAL: White.
  GDK_COLOR_RGB(255, 255, 255),  // SecurityLevel INSECURE: White.
};

LocationBarViewGtk::LocationBarViewGtk(CommandUpdater* command_updater,
    ToolbarModel* toolbar_model, AutocompletePopupPositioner* popup_positioner)
    : profile_(NULL),
      command_updater_(command_updater),
      toolbar_model_(toolbar_model),
      popup_positioner_(popup_positioner),
      disposition_(CURRENT_TAB),
      transition_(PageTransition::TYPED) {
}

LocationBarViewGtk::~LocationBarViewGtk() {
  // All of our widgets should have be children of / owned by the alignment.
  alignment_.Destroy();
}

void LocationBarViewGtk::Init() {
  location_entry_.reset(new AutocompleteEditViewGtk(this,
                                                    toolbar_model_,
                                                    profile_,
                                                    command_updater_,
                                                    popup_positioner_));
  location_entry_->Init();

  alignment_.Own(gtk_alignment_new(0.0, 0.0, 1.0, 1.0));
  gtk_alignment_set_padding(GTK_ALIGNMENT(alignment_.get()),
                            kTopMargin + kBorderThickness,
                            kBottomMargin + kBorderThickness,
                            kEditLeftRightPadding, kEditLeftRightPadding);
  // We will paint for the alignment, to paint the background and border.
  gtk_widget_set_app_paintable(alignment_.get(), TRUE);
  // Have GTK double buffer around the expose signal.
  gtk_widget_set_double_buffered(alignment_.get(), TRUE);
  g_signal_connect(alignment_.get(), "expose-event",
                   G_CALLBACK(&HandleExposeThunk), this);

  gtk_container_add(GTK_CONTAINER(alignment_.get()),
                    location_entry_->widget());
}

void LocationBarViewGtk::SetProfile(Profile* profile) {
  profile_ = profile;
}

void LocationBarViewGtk::Update(const TabContents* contents) {
  location_entry_->Update(contents);
  // The security level (background color) could have changed, etc.
  gtk_widget_queue_draw(alignment_.get());
}

void LocationBarViewGtk::OnAutocompleteAccept(const GURL& url,
      WindowOpenDisposition disposition,
      PageTransition::Type transition,
      const GURL& alternate_nav_url) {
  if (!url.is_valid())
    return;

  location_input_ = UTF8ToWide(url.spec());
  disposition_ = disposition;
  transition_ = transition;

  if (!command_updater_)
    return;

  if (!alternate_nav_url.is_valid()) {
    command_updater_->ExecuteCommand(IDC_OPEN_CURRENT_URL);
    return;
  }

  scoped_ptr<AlternateNavURLFetcher> fetcher(
      new AlternateNavURLFetcher(alternate_nav_url));
  // The AlternateNavURLFetcher will listen for the pending navigation
  // notification that will be issued as a result of the "open URL." It
  // will automatically install itself into that navigation controller.
  command_updater_->ExecuteCommand(IDC_OPEN_CURRENT_URL);
  if (fetcher->state() == AlternateNavURLFetcher::NOT_STARTED) {
    // I'm not sure this should be reachable, but I'm not also sure enough
    // that it shouldn't to stick in a NOTREACHED().  In any case, this is
    // harmless; we can simply let the fetcher get deleted here and it will
    // clean itself up properly.
  } else {
    fetcher.release();  // The navigation controller will delete the fetcher.
  }
}

void LocationBarViewGtk::OnChanged() {
  // TODO(deanm): Here is where we would do layout when we have things like
  // the keyword display, ssl icons, etc.
}

void LocationBarViewGtk::OnInputInProgress(bool in_progress) {
  NOTIMPLEMENTED();
}

SkBitmap LocationBarViewGtk::GetFavIcon() const {
  NOTIMPLEMENTED();
  return SkBitmap();
}

std::wstring LocationBarViewGtk::GetTitle() const {
  NOTIMPLEMENTED();
  return std::wstring();
}

void LocationBarViewGtk::ShowFirstRunBubble() {
  NOTIMPLEMENTED();
}

std::wstring LocationBarViewGtk::GetInputString() const {
  return location_input_;
}

WindowOpenDisposition LocationBarViewGtk::GetWindowOpenDisposition() const {
  return disposition_;
}

PageTransition::Type LocationBarViewGtk::GetPageTransition() const {
  return transition_;
}

void LocationBarViewGtk::AcceptInput() {
  AcceptInputWithDisposition(CURRENT_TAB);
}

void LocationBarViewGtk::AcceptInputWithDisposition(
    WindowOpenDisposition disposition) {
  location_entry_->model()->AcceptInput(disposition, false);
}

void LocationBarViewGtk::FocusLocation() {
  location_entry_->SetFocus();
  location_entry_->SelectAll(true);
}

void LocationBarViewGtk::FocusSearch() {
  location_entry_->SetUserText(L"?");
  location_entry_->SetFocus();
}

void LocationBarViewGtk::UpdatePageActions() {
  NOTIMPLEMENTED();
}

void LocationBarViewGtk::SaveStateToContents(TabContents* contents) {
  NOTIMPLEMENTED();
}

void LocationBarViewGtk::Revert() {
  location_entry_->RevertAll();
}

gboolean LocationBarViewGtk::HandleExpose(GtkWidget* widget,
                                          GdkEventExpose* event) {
  GdkDrawable* drawable = GDK_DRAWABLE(event->window);
  GdkGC* gc = gdk_gc_new(drawable);

  GdkRectangle* alloc_rect = &alignment_.get()->allocation;

  // The area outside of our margin, which includes the border.
  GdkRectangle inner_rect = {
      alloc_rect->x,
      alloc_rect->y + kTopMargin,
      alloc_rect->width,
      alloc_rect->height - kTopMargin - kBottomMargin};

  // Draw our 1px border.  TODO(deanm): Maybe this would be cleaner as an
  // overdrawn stroked rect with a clip to the allocation?
  gdk_gc_set_rgb_fg_color(gc, &kBorderColor);
  gdk_draw_rectangle(drawable, gc, TRUE,
                     inner_rect.x,
                     inner_rect.y,
                     inner_rect.width,
                     kBorderThickness);
  gdk_draw_rectangle(drawable, gc, TRUE,
                     inner_rect.x,
                     inner_rect.y + inner_rect.height - kBorderThickness,
                     inner_rect.width,
                     kBorderThickness);

  // Draw the background within the border.
  gdk_gc_set_rgb_fg_color(gc,
      &kBackgroundColorByLevel[toolbar_model_->GetSchemeSecurityLevel()]);
  gdk_draw_rectangle(drawable, gc, TRUE,
                     inner_rect.x,
                     inner_rect.y + kBorderThickness,
                     inner_rect.width,
                     inner_rect.height - (kBorderThickness * 2));

  g_object_unref(gc);

  return FALSE;  // Continue propagating the expose.
}
<|endoftext|>


<commit_before><commit_msg>Fix the position of the throbber for pinned tabs.  It was wrong before, but we repainted the whole pinned tab so it wasn't as obvious.  With this change, the throbber is placed where the favicon will go.<commit_after><|endoftext|>


<commit_before>///\file conn_http_progressive.cpp
///\brief Contains the main code for the HTTP Progressive Connector

#include <iostream>
#include <queue>
#include <sstream>

#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <mist/socket.h>
#include <mist/http_parser.h>
#include <mist/dtsc.h>
#include <mist/ogg.h>
#include <mist/amf.h>
#include <mist/config.h>
#include <mist/stream.h>
#include <mist/timing.h>

///\brief Holds everything unique to HTTP Connectors.
namespace Connector_HTTP {
  ///\brief Main function for the HTTP Progressive Connector
  ///\param conn A socket describing the connection the client.
  ///\return The exit code of the connector.
  int progressiveConnector(Socket::Connection conn){
    bool progressive_has_sent_header = false;//Indicates whether we have sent a header.
    bool ready4data = false; //Set to true when streaming is to begin.
    DTSC::Stream Strm; //Incoming stream buffer.
    HTTP::Parser HTTP_R, HTTP_S;//HTTP Receiver en HTTP Sender.
    bool inited = false;//Whether the stream is initialized
    Socket::Connection ss( -1);//The Stream Socket, used to connect to the desired stream.
    std::string streamname;//Will contain the name of the stream.

    //MP4 specific variables

    //OGG specific variables
    /*OGG::headerPages oggMeta;
    OGG::Page curOggPage;
    std::map <long long unsigned int, std::vector<JSON::Value> > DTSCBuffer;
    std::map <long long unsigned int, long long unsigned int> prevGran;*/

    unsigned int lastStats = 0;//Indicates the last time that we have sent stats to the server socket.
    unsigned int seek_sec = 0;//Seek position in ms
    unsigned int seek_byte = 0;//Seek position in bytes

    int videoID = -1;
    int audioID = -1;

    while (conn.connected()){
      //Only attempt to parse input when not yet init'ed.
      if ( !inited){
        if (conn.Received().size() || conn.spool()){
          //make sure it ends in a \n
          if ( *(conn.Received().get().rbegin()) != '\n'){
            std::string tmp = conn.Received().get();
            conn.Received().get().clear();
            if (conn.Received().size()){
              conn.Received().get().insert(0, tmp);
            }else{
              conn.Received().append(tmp);
            }
          }
          if (HTTP_R.Read(conn.Received().get())){
#if DEBUG >= 5
            std::cout << "Received request: " << HTTP_R.getUrl() << std::endl;
#endif
            conn.setHost(HTTP_R.GetHeader("X-Origin"));
            //we assume the URL is the stream name with a 3 letter extension
            streamname = HTTP_R.getUrl().substr(1);
            size_t extDot = streamname.rfind('.');
            if (extDot != std::string::npos){
              streamname.resize(extDot);
            }; //strip the extension
            int start = 0;
            if ( !HTTP_R.GetVar("start").empty()){
              start = atoi(HTTP_R.GetVar("start").c_str());
            }
            if ( !HTTP_R.GetVar("starttime").empty()){
              start = atoi(HTTP_R.GetVar("starttime").c_str());
            }
            if ( !HTTP_R.GetVar("apstart").empty()){
              start = atoi(HTTP_R.GetVar("apstart").c_str());
            }
            if ( !HTTP_R.GetVar("ec_seek").empty()){
              start = atoi(HTTP_R.GetVar("ec_seek").c_str());
            }
            if ( !HTTP_R.GetVar("fs").empty()){
              start = atoi(HTTP_R.GetVar("fs").c_str());
            }
            //under 3 hours we assume seconds, otherwise byte position
            if (start < 10800){
              seek_sec = start * 1000; //ms, not s
            }else{
              seek_byte = start; //divide by 1mbit, then *1000 for ms.
            }
            ready4data = true;
            HTTP_R.Clean(); //clean for any possible next requests
          }
        }
      }
      if (ready4data){
        if ( !inited){
          //we are ready, connect the socket!
          ss = Util::Stream::getStream(streamname);
          if ( !ss.connected()){
#if DEBUG >= 1
            fprintf(stderr, "Could not connect to server for %s!\n", streamname.c_str());
#endif
            ss.close();
            HTTP_S.Clean();
            HTTP_S.SetBody("No such stream is available on the system. Please try again.\n");
            conn.SendNow(HTTP_S.BuildResponse("404", "Not found"));
            ready4data = false;
            continue;
          }
          //wait until we have a header
          while ( !Strm.metadata && ss.connected()){
            if (ss.spool()){
              Strm.parsePacket(ss.Received()); //read the metadata
            }else{
              Util::sleep(5);
            }
          }
          int byterate = 0;
          for (JSON::ObjIter objIt = Strm.metadata["tracks"].ObjBegin(); objIt != Strm.metadata["tracks"].ObjEnd(); objIt++){
            if (videoID == -1 && objIt->second["type"].asString() == "video"){
              videoID = objIt->second["trackid"].asInt();
            }
            if (audioID == -1 && objIt->second["type"].asString() == "audio"){
              audioID = objIt->second["trackid"].asInt();
            }
          }
          if (videoID != -1){
            byterate += Strm.getTrackById(videoID)["bps"].asInt();
          }
          if (audioID != -1){
            byterate += Strm.getTrackById(audioID)["bps"].asInt();
          }
          if ( !byterate){byterate = 1;}
          seek_sec = (seek_byte / byterate) * 1000;
          std::stringstream cmd;
          cmd << "t";
          if (videoID != -1){
            cmd << " " << videoID;
          }
          if (audioID != -1){
            cmd << " " << audioID;
          }
          cmd << "\ns " << seek_sec << "\np\n";
          ss.SendNow(cmd.str().c_str(), cmd.str().size());
          inited = true;
        }
        unsigned int now = Util::epoch();
        if (now != lastStats){
          lastStats = now;
          ss.SendNow(conn.getStats("HTTP_Progressive_Ogg").c_str());
        }
        if (ss.spool()){
          while (Strm.parsePacket(ss.Received())){

            if ( !progressive_has_sent_header){
              HTTP_S.Clean(); //make sure no parts of old requests are left in any buffers
              HTTP_S.SetHeader("Content-Type", "video/ogg"); //Send the correct content-type for FLV files
              HTTP_S.protocol = "HTTP/1.0";
              conn.SendNow(HTTP_S.BuildResponse("200", "OK")); //no SetBody = unknown length - this is intentional, we will stream the entire file
              //Fill in header here
              progressive_has_sent_header = true;
            }
            //parse DTSC to MP4 here
          }
        }else{
          Util::sleep(1);
        }
        if ( !ss.connected()){
          break;
        }
      }
    }
    conn.close();
    ss.SendNow(conn.getStats("HTTP_Dynamic").c_str());
    ss.close();
    return 0;
  } //Progressive_Connector main function

} //Connector_HTTP namespace

///\brief The standard process-spawning main function.
int main(int argc, char ** argv){
  Util::Config conf(argv[0], PACKAGE_VERSION);
  JSON::Value capa;
  capa["desc"] = "Enables HTTP protocol progressive streaming.";
  capa["deps"] = "HTTP";
  capa["url_rel"] = "/$.mp4";
  capa["url_match"] = "/$.mp4";
  capa["url_handler"] = "http";
  capa["url_type"] = "mp4";
  capa["socket"] = "http_progressive_mp4";
  conf.addBasicConnectorOptions(capa);
  conf.parseArgs(argc, argv);

  if (conf.getBool("json")){
    std::cout << capa.toString() << std::endl;
    return -1;
  }

  Socket::Server server_socket = Socket::Server("/tmp/mist/http_progressive_mp4");
  if ( !server_socket.connected()){
    return 1;
  }
  conf.activate();

  while (server_socket.connected() && conf.is_active){
    Socket::Connection S = server_socket.accept();
    if (S.connected()){ //check if the new connection is valid
      pid_t myid = fork();
      if (myid == 0){ //if new child, start MAINHANDLER
        return Connector_HTTP::progressiveConnector(S);
      }else{ //otherwise, do nothing or output debugging text
#if DEBUG >= 5
        fprintf(stderr, "Spawned new process %i for socket %i\n", (int)myid, S.getSocket());
#endif
      }
    }
  } //while connected
  server_socket.close();
  return 0;
} //main
<commit_msg>MP4 progressive now bleeding edge!<commit_after>///\file conn_http_progressive.cpp
///\brief Contains the main code for the HTTP Progressive Connector

#include <iostream>
#include <queue>
#include <sstream>

#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <mist/socket.h>
#include <mist/http_parser.h>
#include <mist/dtsc.h>
#include <mist/mp4.h>
#include <mist/amf.h>
#include <mist/config.h>
#include <mist/stream.h>
#include <mist/timing.h>

///\brief Holds everything unique to HTTP Connectors.
namespace Connector_HTTP {
  ///\brief Main function for the HTTP Progressive Connector
  ///\param conn A socket describing the connection the client.
  ///\return The exit code of the connector.
  int progressiveConnector(Socket::Connection conn){
    bool progressive_has_sent_header = false;//Indicates whether we have sent a header.
    bool ready4data = false; //Set to true when streaming is to begin.
    DTSC::Stream Strm; //Incoming stream buffer.
    HTTP::Parser HTTP_R, HTTP_S;//HTTP Receiver en HTTP Sender.
    bool inited = false;//Whether the stream is initialized
    Socket::Connection ss( -1);//The Stream Socket, used to connect to the desired stream.
    std::string streamname;//Will contain the name of the stream.

    //MP4 specific variables
    MP4::DTSC2MP4Converter Conv;

    unsigned int lastStats = 0;//Indicates the last time that we have sent stats to the server socket.
    unsigned int seek_sec = 0;//Seek position in ms
    unsigned int seek_byte = 0;//Seek position in bytes

    int videoID = -1;
    int audioID = -1;

    while (conn.connected()){
      //Only attempt to parse input when not yet init'ed.
      if ( !inited){
        if (conn.Received().size() || conn.spool()){
          //make sure it ends in a \n
          if ( *(conn.Received().get().rbegin()) != '\n'){
            std::string tmp = conn.Received().get();
            conn.Received().get().clear();
            if (conn.Received().size()){
              conn.Received().get().insert(0, tmp);
            }else{
              conn.Received().append(tmp);
            }
          }
          if (HTTP_R.Read(conn.Received().get())){
#if DEBUG >= 5
            std::cout << "Received request: " << HTTP_R.getUrl() << std::endl;
#endif
            conn.setHost(HTTP_R.GetHeader("X-Origin"));
            //we assume the URL is the stream name with a 3 letter extension
            streamname = HTTP_R.getUrl().substr(1);
            size_t extDot = streamname.rfind('.');
            if (extDot != std::string::npos){
              streamname.resize(extDot);
            }; //strip the extension
            int start = 0;
            if ( !HTTP_R.GetVar("start").empty()){
              start = atoi(HTTP_R.GetVar("start").c_str());
            }
            if ( !HTTP_R.GetVar("starttime").empty()){
              start = atoi(HTTP_R.GetVar("starttime").c_str());
            }
            if ( !HTTP_R.GetVar("apstart").empty()){
              start = atoi(HTTP_R.GetVar("apstart").c_str());
            }
            if ( !HTTP_R.GetVar("ec_seek").empty()){
              start = atoi(HTTP_R.GetVar("ec_seek").c_str());
            }
            if ( !HTTP_R.GetVar("fs").empty()){
              start = atoi(HTTP_R.GetVar("fs").c_str());
            }
            //under 3 hours we assume seconds, otherwise byte position
            if (start < 10800){
              seek_sec = start * 1000; //ms, not s
            }else{
              seek_byte = start; //divide by 1mbit, then *1000 for ms.
            }
            ready4data = true;
            HTTP_R.Clean(); //clean for any possible next requests
          }
        }
      }
      if (ready4data){
        if ( !inited){
          //we are ready, connect the socket!
          ss = Util::Stream::getStream(streamname);
          if ( !ss.connected()){
#if DEBUG >= 1
            fprintf(stderr, "Could not connect to server for %s!\n", streamname.c_str());
#endif
            ss.close();
            HTTP_S.Clean();
            HTTP_S.SetBody("No such stream is available on the system. Please try again.\n");
            conn.SendNow(HTTP_S.BuildResponse("404", "Not found"));
            ready4data = false;
            continue;
          }
          //wait until we have a header
          while ( !Strm.metadata && ss.connected()){
            if (ss.spool()){
              Strm.parsePacket(ss.Received()); //read the metadata
            }else{
              Util::sleep(5);
            }
          }
          int byterate = 0;
          for (JSON::ObjIter objIt = Strm.metadata["tracks"].ObjBegin(); objIt != Strm.metadata["tracks"].ObjEnd(); objIt++){
            if (videoID == -1 && objIt->second["type"].asString() == "video"){
              videoID = objIt->second["trackid"].asInt();
            }
            if (audioID == -1 && objIt->second["type"].asString() == "audio"){
              audioID = objIt->second["trackid"].asInt();
            }
          }
          if (videoID != -1){
            byterate += Strm.getTrackById(videoID)["bps"].asInt();
          }
          if (audioID != -1){
            byterate += Strm.getTrackById(audioID)["bps"].asInt();
          }
          if ( !byterate){byterate = 1;}
          seek_sec = (seek_byte / byterate) * 1000;
          std::stringstream cmd;
          cmd << "t";
          if (videoID != -1){
            cmd << " " << videoID;
          }
          if (audioID != -1){
            cmd << " " << audioID;
          }
          cmd << "\ns " << seek_sec << "\np\n";
          ss.SendNow(cmd.str().c_str(), cmd.str().size());
          inited = true;
        }
        unsigned int now = Util::epoch();
        if (now != lastStats){
          lastStats = now;
          ss.SendNow(conn.getStats("HTTP_Progressive_MP4").c_str());
        }
        if (ss.spool()){
          while (Strm.parsePacket(ss.Received())){

            if ( !progressive_has_sent_header){
              HTTP_S.Clean(); //make sure no parts of old requests are left in any buffers
              HTTP_S.SetHeader("Content-Type", "video/MP4"); //Send the correct content-type for FLV files
              HTTP_S.protocol = "HTTP/1.0";
              conn.SendNow(HTTP_S.BuildResponse("200", "OK")); //no SetBody = unknown length - this is intentional, we will stream the entire file
              //Fill in header here
              ss.SendNow(Conv.DTSCMeta2MP4Header(Strm.metadata));//SENDING MP4HADER
              progressive_has_sent_header = true;
            }
            //parse DTSC to MP4 here
            Conv.parseDTSC(Strm.getPacket());//parse 1 file DTSC packet
            if(Conv.sendReady()){//if the converter has a part to send out
              ss.SendNow(Conv.sendString());//send out and clear Convverter buffer
            }
          }
        }else{
          Util::sleep(1);
        }
        if ( !ss.connected()){
          break;
        }
      }
    }
    conn.close();
    ss.SendNow(conn.getStats("HTTP_Dynamic").c_str());
    ss.close();
    return 0;
  } //Progressive_Connector main function

} //Connector_HTTP namespace

///\brief The standard process-spawning main function.
int main(int argc, char ** argv){
  Util::Config conf(argv[0], PACKAGE_VERSION);
  JSON::Value capa;
  capa["desc"] = "Enables HTTP protocol progressive streaming.";
  capa["deps"] = "HTTP";
  capa["url_rel"] = "/$.mp4";
  capa["url_match"] = "/$.mp4";
  capa["url_handler"] = "http";
  capa["url_type"] = "mp4";
  capa["socket"] = "http_progressive_mp4";
  conf.addBasicConnectorOptions(capa);
  conf.parseArgs(argc, argv);

  if (conf.getBool("json")){
    std::cout << capa.toString() << std::endl;
    return -1;
  }

  Socket::Server server_socket = Socket::Server("/tmp/mist/http_progressive_mp4");
  if ( !server_socket.connected()){
    return 1;
  }
  conf.activate();

  while (server_socket.connected() && conf.is_active){
    Socket::Connection S = server_socket.accept();
    if (S.connected()){ //check if the new connection is valid
      pid_t myid = fork();
      if (myid == 0){ //if new child, start MAINHANDLER
        return Connector_HTTP::progressiveConnector(S);
      }else{ //otherwise, do nothing or output debugging text
#if DEBUG >= 5
        fprintf(stderr, "Spawned new process %i for socket %i\n", (int)myid, S.getSocket());
#endif
      }
    }
  } //while connected
  server_socket.close();
  return 0;
} //main
<|endoftext|>