ambedtest version 1.0.0

Added ambedtest (amped test & performance analysis client)
This commit is contained in:
LX3JL 2017-08-09 20:51:32 +02:00
parent c20facc0b4
commit 64b9440068
20 changed files with 2477 additions and 0 deletions

45
ambedtest/cambe.cpp Normal file
View File

@ -0,0 +1,45 @@
//
// cambe.cpp
// ambedtest
//
// Created by Jean-Luc Deltombe (LX3JL) on 16/05/2017.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
//
// xlxd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// xlxd 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#include "main.h"
#include <string.h>
#include "cambe.h"
////////////////////////////////////////////////////////////////////////////////////////
// define
////////////////////////////////////////////////////////////////////////////////////////
// constructor
CAmbe::CAmbe()
{
::memset(m_uiAmbe, 0, sizeof(m_uiAmbe));
}
CAmbe::CAmbe(uint8 *ambe)
{
::memcpy(m_uiAmbe, ambe, sizeof(m_uiAmbe));
}

59
ambedtest/cambe.h Normal file
View File

@ -0,0 +1,59 @@
//
// cambe.h
// ambedtest
//
// Created by Jean-Luc Deltombe (LX3JL) on 16/05/2017.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
//
// xlxd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// xlxd 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#ifndef cambe_h
#define cambe_h
////////////////////////////////////////////////////////////////////////////////////////
// define
// frame sizes
#define AMBE_SIZE 9
////////////////////////////////////////////////////////////////////////////////////////
// class
class CAmbe
{
public:
// constructor
CAmbe();
CAmbe(uint8 *);
// destructor
virtual ~CAmbe() {}
// get
const uint8 *GetData(void) const { return m_uiAmbe; }
protected:
// data
uint8 m_uiAmbe[AMBE_SIZE];
};
////////////////////////////////////////////////////////////////////////////////////////
#endif /* cambe_h */

200
ambedtest/cbuffer.cpp Normal file
View File

@ -0,0 +1,200 @@
//
// cbuffer.cpp
// xlxd
//
// Created by Jean-Luc Deltombe (LX3JL) on 02/11/2015.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
//
// xlxd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// xlxd 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#include "main.h"
#include <string.h>
#include "cbuffer.h"
////////////////////////////////////////////////////////////////////////////////////////
// constructor
CBuffer::CBuffer(uint8 *buffer, int len)
{
resize(len);
::memcpy(data(), buffer, len);
}
////////////////////////////////////////////////////////////////////////////////////////
// set
void CBuffer::Set(uint8 *buffer, int len)
{
resize(len);
::memcpy(data(), buffer, len);
}
void CBuffer::Set(const char *sz)
{
resize(::strlen(sz)+1);
::strcpy((char *)data(), sz);
}
void CBuffer::Append(uint8 *buffer, int len)
{
int n = (int)size();
resize(n+len);
::memcpy(&(data()[n]), buffer, len);
}
void CBuffer::Append(uint8 ui, int len)
{
int n = (int)size();
resize(n+len);
::memset(&(data()[n]), ui, len);
}
void CBuffer::Append(uint8 ui)
{
int n = (int)size();
resize(n+sizeof(uint8));
::memcpy(&(data()[n]), &ui, sizeof(uint8));
}
void CBuffer::Append(uint16 ui)
{
int n = (int)size();
resize(n+sizeof(uint16));
::memcpy(&(data()[n]), &ui, sizeof(uint16));
}
void CBuffer::Append(uint32 ui)
{
int n = (int)size();
resize(n+sizeof(uint32));
::memcpy(&(data()[n]), &ui, sizeof(uint32));
}
void CBuffer::Append(const char *sz)
{
Append((uint8 *)sz, (int)strlen(sz));
Append((uint8)0x00);
}
void CBuffer::ReplaceAt(int i, uint8 ui)
{
if ( size() < (i+sizeof(uint8)) )
{
resize(i+sizeof(uint8));
}
*(uint8 *)(&(data()[i])) = ui;
}
void CBuffer::ReplaceAt(int i, uint16 ui)
{
if ( size() < (i+sizeof(uint16)) )
{
resize(i+sizeof(uint16));
}
*(uint16 *)(&(data()[i])) = ui;
}
void CBuffer::ReplaceAt(int i, uint32 ui)
{
if ( size() < (i+sizeof(uint32)) )
{
resize(i+sizeof(uint32));
}
*(uint32 *)(&(data()[i])) = ui;
}
void CBuffer::ReplaceAt(int i, const uint8 *ptr, int len)
{
if ( size() < (i+len) )
{
resize(i+len);
}
::memcpy(&(data()[i]), ptr, len);
}
////////////////////////////////////////////////////////////////////////////////////////
// operation
int CBuffer::Compare(uint8 *buffer, int len) const
{
int result = -1;
if ( size() >= len )
{
result = ::memcmp(data(), buffer, len);
}
return result;
}
int CBuffer::Compare(uint8 *buffer, int off, int len) const
{
int result = -1;
if ( size() >= (off+len) )
{
result = ::memcmp(&(data()[off]), buffer, len);
}
return result;
}
////////////////////////////////////////////////////////////////////////////////////////
// operator
bool CBuffer::operator ==(const CBuffer &Buffer) const
{
if ( size() == Buffer.size() )
{
return (::memcmp((const char *)data(), (const char *)Buffer.data(), size()) == 0);
}
return false;
}
bool CBuffer::operator ==(const char *sz) const
{
if ( size() == ::strlen(sz) )
{
return (::memcmp((const char *)data(), sz, size()) == 0);
}
return false;
}
CBuffer::operator const char *() const
{
return (const char *)data();
}
////////////////////////////////////////////////////////////////////////////////////////
// debug
void CBuffer::DebugDump(std::ofstream &debugout) const
{
for ( int i = 0; i < size(); i++ )
{
char sz[16];
sprintf(sz, "%02X", data()[i]);
debugout << sz;
if ( i == size()-1 )
{
debugout << std::endl;
}
else
{
debugout << ',';
}
}
}

68
ambedtest/cbuffer.h Normal file
View File

@ -0,0 +1,68 @@
//
// cbuffer.h
// xlxd
//
// Created by Jean-Luc Deltombe (LX3JL) on 02/11/2015.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
//
// xlxd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// xlxd 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#ifndef cbuffer_h
#define cbuffer_h
////////////////////////////////////////////////////////////////////////////////////////
class CBuffer : public std::vector<uint8>
{
public:
// constructor
CBuffer() {};
CBuffer(uint8 *, int);
// destructor
virtual ~CBuffer() {};
// set
void Set(uint8 *, int);
void Set(const char *);
void Append(uint8 *, int);
void Append(uint8, int);
void Append(uint8);
void Append(uint16);
void Append(uint32);
void Append(const char *);
void ReplaceAt(int, uint8);
void ReplaceAt(int, uint16);
void ReplaceAt(int, uint32);
void ReplaceAt(int, const uint8 *, int);
// operation
int Compare(uint8 *, int) const;
int Compare(uint8 *, int, int) const;
// operator
bool operator ==(const CBuffer &) const;
bool operator ==(const char *) const;
operator const char *() const;
// debug
void DebugDump(std::ofstream &) const;
};
////////////////////////////////////////////////////////////////////////////////////////
#endif /* cbuffer_h */

297
ambedtest/ccodecstream.cpp Normal file
View File

@ -0,0 +1,297 @@
//
// ccodecstream.cpp
// xlxd
//
// Created by Jean-Luc Deltombe (LX3JL) on 13/04/2017.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
//
// xlxd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// xlxd 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#include "main.h"
#include <string.h>
#include "ccodecstream.h"
#include "samples.h"
#include "ctranscoder.h"
////////////////////////////////////////////////////////////////////////////////////////
// define
////////////////////////////////////////////////////////////////////////////////////////
// constructor
CCodecStream::CCodecStream(uint16 uiId, uint8 uiCodecIn, uint8 uiCodecOut)
{
m_bStopThread = false;
m_pThread = NULL;
m_uiStreamId = uiId;
m_uiPid = 0;
m_uiCodecIn = uiCodecIn;
m_uiCodecOut = uiCodecOut;
m_bConnected = false;
m_iAmbeSrcPtr = 0;
m_iAmbeDestPtr = 0;
m_uiNbPacketSent = 0;
m_uiNbPacketReceived = 0;
m_uiNbPacketBad = 0;
m_uiNbPacketTimeout = 0;
}
////////////////////////////////////////////////////////////////////////////////////////
// destructor
CCodecStream::~CCodecStream()
{
// close socket
m_Socket.Close();
// kill threads
m_bStopThread = true;
if ( m_pThread != NULL )
{
m_pThread->join();
delete m_pThread;
}
}
////////////////////////////////////////////////////////////////////////////////////////
// initialization
bool CCodecStream::Init(uint16 uiPort)
{
bool ok;
// reset stop flag
m_bStopThread = false;
// copy our test data
if ( m_uiCodecIn == CODEC_AMBE2PLUS )
{
// DMR -> DSTAR
for ( int i = 0; i < sizeof(g_uiDmrSample); i += AMBE_SIZE )
{
CAmbe *ambe = new CAmbe(&(g_uiDmrSample[i]));
m_AmbeSrc.push_back(ambe);
}
for ( int i = 0; i < sizeof(g_uiDstarSample); i += AMBE_SIZE )
{
CAmbe *ambe = new CAmbe(&(g_uiDstarSample[i]));
m_AmbeDest.push_back(ambe);
}
}
else
{
// DSTAR -> DMR
for ( int i = 0; i < sizeof(g_uiDstarSample); i += AMBE_SIZE )
{
CAmbe *ambe = new CAmbe(&(g_uiDstarSample[i]));
m_AmbeSrc.push_back(ambe);
}
for ( int i = 0; i < sizeof(g_uiDmrSample); i += AMBE_SIZE )
{
CAmbe *ambe = new CAmbe(&(g_uiDmrSample[i]));
m_AmbeDest.push_back(ambe);
}
}
// create server's IP
m_Ip = g_Transcoder.GetAmbedIp();
m_uiPort = uiPort;
// create our socket
ok = m_Socket.Open(uiPort);
if ( ok )
{
// start thread;
m_pThread = new std::thread(CCodecStream::Thread, this);
m_bConnected = true;
m_FrameTimer.Now();
ResetStats();
}
else
{
std::cout << "Error opening socket on port UDP" << uiPort << " on ip " << m_Ip << std::endl;
m_bConnected = false;
}
// done
return ok;
}
void CCodecStream::Close(void)
{
// close socket
m_bConnected = false;
m_Socket.Close();
// kill threads
m_bStopThread = true;
if ( m_pThread != NULL )
{
m_pThread->join();
delete m_pThread;
m_pThread = NULL;
}
}
////////////////////////////////////////////////////////////////////////////////////////
// thread
void CCodecStream::Thread(CCodecStream *This)
{
while ( !This->m_bStopThread )
{
This->Task();
}
}
void CCodecStream::Task(void)
{
CBuffer Buffer;
CIp Ip;
uint8 Ambe[AMBE_SIZE];
// connected ?
if ( m_bConnected )
{
// time to send next packet to be transcoded ?
/*if ( m_FrameTimer.DurationSinceNow() >= 0.020 )
{
// yes
m_FrameTimer.Now();
// encode packet @ send it
EncodeAmbePacket(&Buffer, m_AmbeSrc[m_iAmbeSrcPtr]->GetData());
m_Socket.Send(Buffer, m_Ip, m_uiPort);
// and increment pointer
m_iAmbeSrcPtr = (m_iAmbeSrcPtr + 1) % m_AmbeSrc.size();
m_uiNbPacketSent++;
}*/
// any packt to send to trancoder ?
uint32 uiNbPacketToSend = (uint32)(m_FrameTimer.DurationSinceNow() * 50.0) - m_uiNbPacketSent;
if ( uiNbPacketToSend > 0 )
{
for ( int i = 0; i < uiNbPacketToSend; i++ )
{
// encode packet @ send it
EncodeAmbePacket(&Buffer, m_AmbeSrc[m_iAmbeSrcPtr]->GetData());
m_Socket.Send(Buffer, m_Ip, m_uiPort);
// and increment pointer
m_iAmbeSrcPtr = (m_iAmbeSrcPtr + 1) % m_AmbeSrc.size();
m_uiNbPacketSent++;
}
}
// any packet from transcoder
if ( m_Socket.Receive(&Buffer, &Ip, 1) != -1 )
{
// crack
if ( IsValidAmbePacket(Buffer, Ambe) )
{
m_TimeoutTimer.Now();
// check the PID
// check the transcoded packet
/*if ( ::memcmp(Ambe, m_AmbeDest[m_iAmbeDestPtr]->GetData(), AMBE_SIZE) != 0 )
{
m_uiNbPacketBad++;
::memcpy((void *)m_AmbeDest[m_iAmbeDestPtr]->GetData(), Ambe, AMBE_SIZE);
}*/
// and increment pointer
m_iAmbeDestPtr = (m_iAmbeDestPtr + 1) % m_AmbeDest.size();
m_uiNbPacketReceived++;
}
}
}
// display stats
if ( m_DisplayStatsTimer.DurationSinceNow() >= 2.0 )
{
m_DisplayStatsTimer.Now();
DisplayStats();
}
// handle timeout
if ( m_TimeoutTimer.DurationSinceNow() >= (TRANSCODER_AMBEPACKET_TIMEOUT/1000.0f) )
{
//std::cout << "ambed packet timeout" << std::endl;
m_uiNbPacketTimeout++;
}
}
////////////////////////////////////////////////////////////////////////////////////////
/// packet decoding helpers
bool CCodecStream::IsValidAmbePacket(const CBuffer &Buffer, uint8 *Ambe)
{
bool valid = false;
if ( (Buffer.size() == 11) && (Buffer.data()[0] == m_uiCodecOut) )
{
::memcpy(Ambe, &(Buffer.data()[2]), 9);
valid = true;
}
return valid;
}
////////////////////////////////////////////////////////////////////////////////////////
/// packet encoding helpers
void CCodecStream::EncodeAmbePacket(CBuffer *Buffer, const uint8 *Ambe)
{
Buffer->clear();
Buffer->Append(m_uiCodecIn);
Buffer->Append(m_uiPid);
Buffer->Append((uint8 *)Ambe, 9);
}
////////////////////////////////////////////////////////////////////////////////////////
// stats helpers
void CCodecStream::ResetStats(void)
{
m_StatsTimer.Now();
m_DisplayStatsTimer.Now();
m_TimeoutTimer.Now();
m_uiNbPacketSent = 0;
m_uiNbPacketReceived = 0;
m_uiNbPacketBad = 0;
m_uiNbPacketTimeout = 0;
}
void CCodecStream::DisplayStats(void)
{
//double fps = (double)m_uiNbPacketSent / m_StatsTimer.DurationSinceNow();
double fps = (double)m_uiNbPacketReceived / m_StatsTimer.DurationSinceNow();
std::cout << "Stream " << (int)m_uiStreamId << " (" << (int)m_uiCodecIn << "->" << (int)m_uiCodecOut << ") : ";
std::cout << m_uiNbPacketSent << " / " << m_uiNbPacketReceived << " / " << m_uiNbPacketTimeout;
//std::cout << " / " << m_uiNbPacketBad;
std::cout << " ; " << fps << " fps";
std::cout << std::endl;
m_uiNbPacketBad = 0;
}

114
ambedtest/ccodecstream.h Normal file
View File

@ -0,0 +1,114 @@
//
// ccodecstream.h
// xlxd
//
// Created by Jean-Luc Deltombe (LX3JL) on 13/04/2017.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
//
// xlxd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// xlxd 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#ifndef ccodecstream_h
#define ccodecstream_h
#include "csemaphore.h"
#include "cudpsocket.h"
#include "ctimepoint.h"
#include "cambe.h"
////////////////////////////////////////////////////////////////////////////////////////
// define
// frame sizes
#define AMBE_SIZE 9
#define AMBEPLUS_SIZE 9
////////////////////////////////////////////////////////////////////////////////////////
// class
class CCodecStream
{
public:
// constructor
CCodecStream(uint16, uint8, uint8);
// destructor
virtual ~CCodecStream();
// initialization
bool Init(uint16);
void Close(void);
// get
bool IsConnected(void) const { return m_bConnected; }
uint16 GetStreamId(void) const { return m_uiStreamId; }
// task
static void Thread(CCodecStream *);
void Task(void);
protected:
// packet decoding helpers
bool IsValidAmbePacket(const CBuffer &, uint8 *);
// packet encoding helpers
void EncodeAmbePacket(CBuffer *, const uint8 *);
// stats helpers
void ResetStats(void);
void DisplayStats(void);
protected:
// test data
std::vector<CAmbe *> m_AmbeSrc;
int m_iAmbeSrcPtr;
std::vector<CAmbe *> m_AmbeDest;
int m_iAmbeDestPtr;
// data
uint16 m_uiStreamId;
uint16 m_uiPort;
uint8 m_uiPid;
uint8 m_uiCodecIn;
uint8 m_uiCodecOut;
// socket
CIp m_Ip;
CUdpSocket m_Socket;
bool m_bConnected;
// thread
bool m_bStopThread;
std::thread *m_pThread;
CTimePoint m_TimeoutTimer;
CTimePoint m_FrameTimer;
// stats
CTimePoint m_StatsTimer;
CTimePoint m_DisplayStatsTimer;
uint32 m_uiNbPacketSent;
uint32 m_uiNbPacketReceived;
uint32 m_uiNbPacketBad;
uint32 m_uiNbPacketTimeout;
};
////////////////////////////////////////////////////////////////////////////////////////
#endif /* ccodecstream_h */

91
ambedtest/cip.cpp Normal file
View File

@ -0,0 +1,91 @@
//
// cip.cpp
// xlxd
//
// Created by Jean-Luc Deltombe (LX3JL) on 31/10/2015.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
//
// xlxd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// xlxd 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#include "main.h"
#include <string.h>
#include "cip.h"
#include <netdb.h>
////////////////////////////////////////////////////////////////////////////////////////
// constructors
CIp::CIp()
{
::memset(&m_Addr, 0, sizeof(m_Addr));
m_Addr.sin_family = AF_INET;
}
CIp::CIp(const char *sz)
{
::memset(&m_Addr, 0, sizeof(m_Addr));
m_Addr.sin_family = AF_INET;
// try xxx.xxx.xxx.xxxx first
m_Addr.sin_addr.s_addr = inet_addr(sz);
if ( m_Addr.sin_addr.s_addr == INADDR_NONE )
{
// otherwise try to resolve via dns
hostent *record = gethostbyname(sz);
if( record != NULL )
{
m_Addr.sin_addr.s_addr = ((in_addr * )record->h_addr)->s_addr;
}
}
}
CIp::CIp(const struct sockaddr_in *sa)
{
::memcpy(&m_Addr, sa, sizeof(m_Addr));
}
CIp::CIp(const CIp &ip)
{
::memcpy(&m_Addr, &ip.m_Addr, sizeof(m_Addr));
}
////////////////////////////////////////////////////////////////////////////////////////
// set
void CIp::SetSockAddr(struct sockaddr_in *sa)
{
::memcpy(&m_Addr, sa, sizeof(m_Addr));
}
////////////////////////////////////////////////////////////////////////////////////////
// operator
bool CIp::operator ==(const CIp &ip) const
{
return ( (ip.m_Addr.sin_family == m_Addr.sin_family) &&
(ip.m_Addr.sin_addr.s_addr == m_Addr.sin_addr.s_addr) &&
(ip.m_Addr.sin_port == m_Addr.sin_port)) ;
}
CIp::operator const char *() const
{
return ::inet_ntoa(m_Addr.sin_addr);
}

59
ambedtest/cip.h Normal file
View File

@ -0,0 +1,59 @@
//
// cip.h
// xlxd
//
// Created by Jean-Luc Deltombe (LX3JL) on 31/10/2015.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
//
// xlxd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// xlxd 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#ifndef cip_h
#define cip_h
////////////////////////////////////////////////////////////////////////////////////////
// class
class CIp
{
public:
// constructors
CIp();
//CIp(uint8, uint8, uint8, uint8);
CIp(const struct sockaddr_in *);
CIp(const char *);
CIp(const CIp &);
// destructor
virtual ~CIp() {};
// sockaddr
void SetSockAddr(struct sockaddr_in *);
struct sockaddr_in *GetSockAddr(void) { return &m_Addr; }
// operator
bool operator ==(const CIp &) const;
operator const char *() const;
protected:
// data
struct sockaddr_in m_Addr;
};
////////////////////////////////////////////////////////////////////////////////////////
#endif /* cip_h */

72
ambedtest/csemaphore.cpp Normal file
View File

@ -0,0 +1,72 @@
//
// csemaphore.cpp
// xlxd
//
// Created by Jean-Luc Deltombe (LX3JL) on 16/04/2017.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
//
// xlxd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// xlxd 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#include "main.h"
#include "csemaphore.h"
////////////////////////////////////////////////////////////////////////////////////////
// constructor
CSemaphore::CSemaphore()
{
// Initialized as locked.
m_Count = 0;
}
////////////////////////////////////////////////////////////////////////////////////////
// operation
void CSemaphore::Reset(void)
{
std::unique_lock<decltype(m_Mutex)> lock(m_Mutex);
m_Count = 0;
}
void CSemaphore::Notify(void)
{
std::unique_lock<std::mutex> lock(m_Mutex);
m_Count++;
m_Condition.notify_one();
}
void CSemaphore::Wait(void)
{
std::unique_lock<std::mutex> lock(m_Mutex);
m_Condition.wait(lock, [&]{ return m_Count > 0; });
m_Count--;
}
bool CSemaphore::WaitFor(uint ms)
{
std::chrono::milliseconds timespan(ms);
std::unique_lock<decltype(m_Mutex)> lock(m_Mutex);
auto ok = m_Condition.wait_for(lock, timespan, [&]{ return m_Count > 0; });
if ( ok )
{
m_Count--;
}
return ok;
}

56
ambedtest/csemaphore.h Normal file
View File

@ -0,0 +1,56 @@
//
// csemaphore.h
// xlxd
//
// Created by Jean-Luc Deltombe (LX3JL) on 16/04/2017.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
//
// xlxd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// xlxd 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#ifndef csemaphore_h
#define csemaphore_h
////////////////////////////////////////////////////////////////////////////////////////
// class
class CSemaphore
{
public:
// constructor
CSemaphore();
// destructor
virtual ~CSemaphore() {};
// operation
void Reset(void);
void Notify(void);
void Wait(void);
bool WaitFor(uint);
protected:
// data
std::mutex m_Mutex;
std::condition_variable m_Condition;
size_t m_Count;
};
////////////////////////////////////////////////////////////////////////////////////////
#endif /* csemaphore_h */

53
ambedtest/ctimepoint.cpp Normal file
View File

@ -0,0 +1,53 @@
//
// ctimepoint.cpp
// xlxd
//
// Created by Jean-Luc Deltombe (LX3JL) on 05/11/2015.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
//
// xlxd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// xlxd 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#include "main.h"
#include "ctimepoint.h"
////////////////////////////////////////////////////////////////////////////////////////
// constructor
CTimePoint::CTimePoint()
{
m_TimePoint = std::chrono::steady_clock::now();
}
////////////////////////////////////////////////////////////////////////////////////////
// operation
double CTimePoint::DurationSinceNow(void) const
{
std::chrono::steady_clock::time_point Now = std::chrono::steady_clock::now();
std::chrono::steady_clock::duration time_span = (Now - m_TimePoint);
return double(time_span.count()) * std::chrono::steady_clock::period::num / std::chrono::steady_clock::period::den;
}
////////////////////////////////////////////////////////////////////////////////////////
// task
void CTimePoint::TaskSleepFor(uint ms)
{
std::chrono::milliseconds timespan(ms);
std::this_thread::sleep_for(timespan);
}

55
ambedtest/ctimepoint.h Normal file
View File

@ -0,0 +1,55 @@
//
// ctimepoint.h
// xlxd
//
// Created by Jean-Luc Deltombe (LX3JL) on 05/11/2015.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
//
// xlxd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// xlxd 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#ifndef ctimepoint_h
#define ctimepoint_h
////////////////////////////////////////////////////////////////////////////////////////
// class
class CTimePoint : public std::chrono::steady_clock::time_point
{
public:
// constructor
CTimePoint();
// destructor
virtual ~CTimePoint() {}
// operation
void Now(void) { m_TimePoint = std::chrono::steady_clock::now(); }
double DurationSinceNow(void) const;
// task
static void TaskSleepFor(uint);
protected:
// data
std::chrono::steady_clock::time_point m_TimePoint;
};
////////////////////////////////////////////////////////////////////////////////////////
#endif /* ctimepoint_h */

388
ambedtest/ctranscoder.cpp Normal file
View File

@ -0,0 +1,388 @@
//
// ctranscoder.cpp
// xlxd
//
// Created by Jean-Luc Deltombe (LX3JL) on 13/04/2017.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
//
// xlxd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// xlxd 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#include "main.h"
#include "ctranscoder.h"
////////////////////////////////////////////////////////////////////////////////////////
// define
// status
#define STATUS_IDLE 0
#define STATUS_LOGGED 1
// timeout
#define AMBED_OPENSTREAM_TIMEOUT 200 // in ms
////////////////////////////////////////////////////////////////////////////////////////
CTranscoder g_Transcoder;
////////////////////////////////////////////////////////////////////////////////////////
// constructor
CTranscoder::CTranscoder()
{
m_bStopThread = false;
m_pThread = NULL;
m_Streams.reserve(12);
m_bConnected = false;
m_LastKeepaliveTime.Now();
m_LastActivityTime.Now();
m_bStreamOpened = false;
m_StreamidOpenStream = 0;
m_PortOpenStream = 0;
}
////////////////////////////////////////////////////////////////////////////////////////
// destructor
CTranscoder::~CTranscoder()
{
// close all streams
m_Mutex.lock();
{
for ( int i = 0; i < m_Streams.size(); i++ )
{
delete m_Streams[i];
}
m_Streams.clear();
}
m_Mutex.unlock();
// kill threads
m_bStopThread = true;
if ( m_pThread != NULL )
{
m_pThread->join();
delete m_pThread;
}
}
////////////////////////////////////////////////////////////////////////////////////////
// initialization
bool CTranscoder::Init(const CIp &ListenIp, const CIp &AmbedIp)
{
bool ok;
// reset stop flag
m_bStopThread = false;
// create server's IP
m_ListenIp = ListenIp;
m_AmbedIp = AmbedIp;
// create our socket
ok = m_Socket.Open(TRANSCODER_PORT);
if ( ok )
{
// start thread;
m_pThread = new std::thread(CTranscoder::Thread, this);
}
else
{
std::cout << "Error opening socket on port UDP" << TRANSCODER_PORT << " on ip " << m_AmbedIp << std::endl;
}
// done
return ok;
}
void CTranscoder::Close(void)
{
// close socket
m_Socket.Close();
// close all streams
m_Mutex.lock();
{
for ( int i = 0; i < m_Streams.size(); i++ )
{
delete m_Streams[i];
}
m_Streams.clear();
}
m_Mutex.unlock();
// kill threads
m_bStopThread = true;
if ( m_pThread != NULL )
{
m_pThread->join();
delete m_pThread;
m_pThread = NULL;
}
}
////////////////////////////////////////////////////////////////////////////////////////
// thread
void CTranscoder::Thread(CTranscoder *This)
{
while ( !This->m_bStopThread )
{
This->Task();
}
}
void CTranscoder::Task(void)
{
CBuffer Buffer;
CIp Ip;
uint16 StreamId;
uint16 Port;
// anything coming in from codec server ?
//if ( (m_Socket.Receive(&Buffer, &Ip, 20) != -1) && (Ip == m_Ip) )
if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 )
{
m_LastActivityTime.Now();
// crack packet
if ( IsValidStreamDescrPacket(Buffer, &StreamId, &Port) )
{
//std::cout << "Transcoder stream " << (int) StreamId << " descr packet " << std::endl;
m_bStreamOpened = true;
m_StreamidOpenStream = StreamId;
m_PortOpenStream = Port;
m_SemaphoreOpenStream.Notify();
}
else if ( IsValidNoStreamAvailablePacket(Buffer) )
{
m_bStreamOpened = false;
m_SemaphoreOpenStream.Notify();
}
else if ( IsValidKeepAlivePacket(Buffer) )
{
if ( !m_bConnected )
{
std::cout << "Transcoder connected at " << Ip << std::endl;
}
m_bConnected = true;
}
}
// handle end of streaming timeout
//CheckStreamsTimeout();
// handle queue from reflector
//HandleQueue();
// keep client alive
if ( m_LastKeepaliveTime.DurationSinceNow() > TRANSCODER_KEEPALIVE_PERIOD )
{
//
HandleKeepalives();
// update time
m_LastKeepaliveTime.Now();
}
}
////////////////////////////////////////////////////////////////////////////////////////
// manage streams
CCodecStream *CTranscoder::GetStream(uint8 uiCodecIn)
{
CBuffer Buffer;
CCodecStream *stream = NULL;
// do we need transcoding
if ( uiCodecIn != CODEC_NONE )
{
// are we connected to server
if ( m_bConnected )
{
// yes, post openstream request
EncodeOpenstreamPacket(&Buffer, uiCodecIn, (uiCodecIn == CODEC_AMBEPLUS) ? CODEC_AMBE2PLUS : CODEC_AMBEPLUS);
m_Socket.Send(Buffer, m_AmbedIp, TRANSCODER_PORT);
// wait relpy here
if ( m_SemaphoreOpenStream.WaitFor(AMBED_OPENSTREAM_TIMEOUT) )
{
if ( m_bStreamOpened )
{
std::cout << "ambed openstream(" << m_StreamidOpenStream << ") ok" << std::endl;
// create stream object
stream = new CCodecStream(m_StreamidOpenStream, uiCodecIn, (uiCodecIn == CODEC_AMBEPLUS) ? CODEC_AMBE2PLUS : CODEC_AMBEPLUS);
// init it
if ( stream->Init(m_PortOpenStream) )
{
// and append to list
Lock();
m_Streams.push_back(stream);
Unlock();
}
else
{
// send close packet
EncodeClosestreamPacket(&Buffer, stream->GetStreamId());
m_Socket.Send(Buffer, m_AmbedIp, TRANSCODER_PORT);
// and delete
delete stream;
stream = NULL;
}
}
else
{
std::cout << "ambed openstream failed (no suitable channel available)" << std::endl;
}
}
else
{
std::cout << "ambed openstream timeout" << std::endl;
}
}
}
return stream;
}
void CTranscoder::ReleaseStream(CCodecStream *stream)
{
CBuffer Buffer;
if ( stream != NULL )
{
// look for the stream
bool found = false;
Lock();
{
for ( int i = 0; (i < m_Streams.size()) && !found; i++ )
{
// compare object pointers
if ( (m_Streams[i]) == stream )
{
// send close packet
EncodeClosestreamPacket(&Buffer, m_Streams[i]->GetStreamId());
m_Socket.Send(Buffer, m_AmbedIp, TRANSCODER_PORT);
// and close it
m_Streams[i]->Close();
delete m_Streams[i];
m_Streams.erase(m_Streams.begin()+i);
found = true;
}
}
}
Unlock();
}
}
////////////////////////////////////////////////////////////////////////////////////////
// keepalive helpers
void CTranscoder::HandleKeepalives(void)
{
CBuffer keepalive;
// send keepalive
EncodeKeepAlivePacket(&keepalive);
m_Socket.Send(keepalive, m_AmbedIp, TRANSCODER_PORT);
// check if still with us
if ( m_bConnected && (m_LastActivityTime.DurationSinceNow() >= TRANSCODER_KEEPALIVE_TIMEOUT) )
{
// no, disconnect
m_bConnected = false;
std::cout << "Transcoder keepalive timeout" << std::endl;
}
}
////////////////////////////////////////////////////////////////////////////////////////
// packet decoding helpers
bool CTranscoder::IsValidKeepAlivePacket(const CBuffer &Buffer)
{
uint8 tag[] = { 'A','M','B','E','D','P','O','N','G' };
bool valid = false;
if ( (Buffer.size() == 9) && (Buffer.Compare(tag, sizeof(tag)) == 0) )
{
valid = true;
}
return valid;
}
bool CTranscoder::IsValidStreamDescrPacket(const CBuffer &Buffer, uint16 *Id, uint16 *Port)
{
uint8 tag[] = { 'A','M','B','E','D','S','T','D' };
bool valid = false;
if ( (Buffer.size() == 14) && (Buffer.Compare(tag, sizeof(tag)) == 0) )
{
*Id = *(uint16 *)(&Buffer.data()[8]);
*Port = *(uint16 *)(&Buffer.data()[10]);
// uint8 CodecIn = Buffer.data()[12];
// uint8 CodecOut = Buffer.data()[13];
valid = true;
}
return valid;
}
bool CTranscoder::IsValidNoStreamAvailablePacket(const CBuffer&Buffer)
{
uint8 tag[] = { 'A','M','B','E','D','B','U','S','Y' };
return ( (Buffer.size() == 9) && (Buffer.Compare(tag, sizeof(tag)) == 0) );
}
////////////////////////////////////////////////////////////////////////////////////////
// packet encoding helpers
void CTranscoder::EncodeKeepAlivePacket(CBuffer *Buffer)
{
uint8 tag[] = { 'A','M','B','E','D','P','I','N','G' };
Buffer->Set(tag, sizeof(tag));
Buffer->Append((uint8 *)(const char *)"XLX000 ", 8);
}
void CTranscoder::EncodeOpenstreamPacket(CBuffer *Buffer, uint8 uiCodecIn, uint8 uiCodecOut)
{
uint8 tag[] = { 'A','M','B','E','D','O','S' };
Buffer->Set(tag, sizeof(tag));
Buffer->Append((uint8 *)(const char *)"XLX000 ", 8);
Buffer->Append((uint8)uiCodecIn);
Buffer->Append((uint8)uiCodecOut);
}
void CTranscoder::EncodeClosestreamPacket(CBuffer *Buffer, uint16 uiStreamId)
{
uint8 tag[] = { 'A','M','B','E','D','C','S' };
Buffer->Set(tag, sizeof(tag));
Buffer->Append((uint16)uiStreamId);
}

113
ambedtest/ctranscoder.h Normal file
View File

@ -0,0 +1,113 @@
//
// ctranscoder.h
// xlxd
//
// Created by Jean-Luc Deltombe (LX3JL) on 13/04/2017.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
//
// xlxd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// xlxd 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#ifndef ctranscoder_h
#define ctranscoder_h
#include "csemaphore.h"
#include "ccodecstream.h"
#include "cudpsocket.h"
////////////////////////////////////////////////////////////////////////////////////////
// define
////////////////////////////////////////////////////////////////////////////////////////
// class
class CTranscoder
{
public:
// constructor
CTranscoder();
// destructor
virtual ~CTranscoder();
// initialization
bool Init(const CIp &, const CIp &);
void Close(void);
// locks
void Lock(void) { m_Mutex.lock(); }
void Unlock(void) { m_Mutex.unlock(); }
// get
const CIp &GetListenIp(void) const { return m_ListenIp; }
const CIp &GetAmbedIp(void) const { return m_AmbedIp; }
bool IsAmbedConnected(void) const { return m_bConnected; }
// manage streams
CCodecStream *GetStream(uint8);
void ReleaseStream(CCodecStream *);
// task
static void Thread(CTranscoder *);
void Task(void);
protected:
// keepalive helpers
void HandleKeepalives(void);
// packet decoding helpers
bool IsValidKeepAlivePacket(const CBuffer &);
bool IsValidStreamDescrPacket(const CBuffer &, uint16 *, uint16 *);
bool IsValidNoStreamAvailablePacket(const CBuffer&);
// packet encoding helpers
void EncodeKeepAlivePacket(CBuffer *);
void EncodeOpenstreamPacket(CBuffer *, uint8, uint8);
void EncodeClosestreamPacket(CBuffer *, uint16);
protected:
// IP's
CIp m_ListenIp;
CIp m_AmbedIp;
// streams
std::mutex m_Mutex;
std::vector<CCodecStream *> m_Streams;
// sync objects for Openstream
CSemaphore m_SemaphoreOpenStream;
bool m_bStreamOpened;
uint16 m_StreamidOpenStream;
uint16 m_PortOpenStream;
// thread
bool m_bStopThread;
std::thread *m_pThread;
// socket
CUdpSocket m_Socket;
bool m_bConnected;
// time
CTimePoint m_LastKeepaliveTime;
CTimePoint m_LastActivityTime;
};
////////////////////////////////////////////////////////////////////////////////////////
#endif /* ctranscoder_h */

173
ambedtest/cudpsocket.cpp Normal file
View File

@ -0,0 +1,173 @@
//
// cudpsocket.cpp
// xlxd
//
// Created by Jean-Luc Deltombe (LX3JL) on 31/10/2015.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
//
// xlxd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// xlxd 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#include "main.h"
#include <string.h>
#include "cudpsocket.h"
#include "ctranscoder.h"
////////////////////////////////////////////////////////////////////////////////////////
// constructor
CUdpSocket::CUdpSocket()
{
m_Socket = -1;
}
////////////////////////////////////////////////////////////////////////////////////////
// destructor
CUdpSocket::~CUdpSocket()
{
if ( m_Socket != -1 )
{
Close();
}
}
////////////////////////////////////////////////////////////////////////////////////////
// open & close
bool CUdpSocket::Open(uint16 uiPort)
{
bool open = false;
// create socket
m_Socket = socket(PF_INET,SOCK_DGRAM,0);
if ( m_Socket != -1 )
{
// initialize sockaddr struct
::memset(&m_SocketAddr, 0, sizeof(struct sockaddr_in));
m_SocketAddr.sin_family = AF_INET;
m_SocketAddr.sin_port = htons(uiPort);
m_SocketAddr.sin_addr.s_addr = inet_addr(g_Transcoder.GetListenIp());
if ( bind(m_Socket, (struct sockaddr *)&m_SocketAddr, sizeof(struct sockaddr_in)) == 0 )
{
fcntl(m_Socket, F_SETFL, O_NONBLOCK);
open = true;
}
else
{
close(m_Socket);
m_Socket = -1;
}
}
// done
return open;
}
void CUdpSocket::Close(void)
{
if ( m_Socket != -1 )
{
close(m_Socket);
m_Socket = -1;
}
}
////////////////////////////////////////////////////////////////////////////////////////
// read
int CUdpSocket::Receive(CBuffer *Buffer, CIp *Ip, int timeout)
{
struct sockaddr_in Sin;
fd_set FdSet;
unsigned int uiFromLen = sizeof(struct sockaddr_in);
int iRecvLen = -1;
struct timeval tv;
// socket valid ?
if ( m_Socket != -1 )
{
// control socket
FD_ZERO(&FdSet);
FD_SET(m_Socket, &FdSet);
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000;
select(m_Socket + 1, &FdSet, 0, 0, &tv);
// allocate buffer
Buffer->resize(UDP_BUFFER_LENMAX);
// read
iRecvLen = (int)recvfrom(m_Socket,
(void *)Buffer->data(), UDP_BUFFER_LENMAX,
0, (struct sockaddr *)&Sin, &uiFromLen);
// handle
if ( iRecvLen != -1 )
{
// adjust buffer size
Buffer->resize(iRecvLen);
// get IP
Ip->SetSockAddr(&Sin);
}
}
// done
return iRecvLen;
}
////////////////////////////////////////////////////////////////////////////////////////
// write
int CUdpSocket::Send(const CBuffer &Buffer, const CIp &Ip)
{
CIp temp(Ip);
return (int)::sendto(m_Socket,
(void *)Buffer.data(), Buffer.size(),
0, (struct sockaddr *)temp.GetSockAddr(), sizeof(struct sockaddr_in));
}
int CUdpSocket::Send(const char *Buffer, const CIp &Ip)
{
CIp temp(Ip);
return (int)::sendto(m_Socket,
(void *)Buffer, ::strlen(Buffer),
0, (struct sockaddr *)temp.GetSockAddr(), sizeof(struct sockaddr_in));
}
int CUdpSocket::Send(const CBuffer &Buffer, const CIp &Ip, uint16 destport)
{
CIp temp(Ip);
temp.GetSockAddr()->sin_port = htons(destport);
return (int)::sendto(m_Socket,
(void *)Buffer.data(), Buffer.size(),
0, (struct sockaddr *)temp.GetSockAddr(), sizeof(struct sockaddr_in));
}
int CUdpSocket::Send(const char *Buffer, const CIp &Ip, uint16 destport)
{
CIp temp(Ip);
temp.GetSockAddr()->sin_port = htons(destport);
return (int)::sendto(m_Socket,
(void *)Buffer, ::strlen(Buffer),
0, (struct sockaddr *)temp.GetSockAddr(), sizeof(struct sockaddr_in));
}

78
ambedtest/cudpsocket.h Normal file
View File

@ -0,0 +1,78 @@
//
// cudpsocket.h
// xlxd
//
// Created by Jean-Luc Deltombe (LX3JL) on 31/10/2015.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
//
// xlxd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// xlxd 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#ifndef cudpsocket_h
#define cudpsocket_h
#include <sys/types.h>
//#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include "cip.h"
#include "cbuffer.h"
////////////////////////////////////////////////////////////////////////////////////////
// define
#define UDP_BUFFER_LENMAX 1024
////////////////////////////////////////////////////////////////////////////////////////
// class
class CUdpSocket
{
public:
// constructor
CUdpSocket();
// destructor
~CUdpSocket();
// open & close
bool Open(uint16);
void Close(void);
int GetSocket(void) { return m_Socket; }
// read
int Receive(CBuffer *, CIp *, int);
// write
int Send(const CBuffer &, const CIp &);
int Send(const CBuffer &, const CIp &, uint16);
int Send(const char *, const CIp &);
int Send(const char *, const CIp &, uint16);
protected:
// data
int m_Socket;
struct sockaddr_in m_SocketAddr;
};
////////////////////////////////////////////////////////////////////////////////////////
#endif /* cudpsocket_h */

77
ambedtest/main.cpp Normal file
View File

@ -0,0 +1,77 @@
//
// main.cpp
// ambedtest
//
// Created by Jean-Luc Deltombe (LX3JL) on 12/05/2017.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
//
// xlxd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// xlxd 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#include "main.h"
#include "ctranscoder.h"
#define NB_STREAM 1
int main(int argc, const char * argv[])
{
std::vector<CCodecStream *> Streams;
// check args
if ( argc != 5 )
{
std::cout << "Usage: ambedtest myip ambedip nbdmrstreams nbdstarstreams" << std::endl;
std::cout << "example: ambed 192.168.178.212 127.0.0.1 2 2" << std::endl;
return 1;
}
// init the transcoder
std::cout << "Connecting to ambed server " << std::endl;
g_Transcoder.Init(CIp(argv[1]), CIp(argv[2]));
while ( !g_Transcoder.IsAmbedConnected() );
std::cout << "Press enter to start test" << std::endl;
std::cin.get();
// create streams
int nDmr = atoi(argv[3]);
int nDstar = atoi(argv[4]);
for ( int i = 0; i < nDmr; i++ )
{
CTimePoint::TaskSleepFor(300);
Streams.push_back(g_Transcoder.GetStream(CODEC_AMBE2PLUS));
}
for ( int i = 0; i < nDstar; i++ )
{
CTimePoint::TaskSleepFor(300);
Streams.push_back(g_Transcoder.GetStream(CODEC_AMBEPLUS));
}
// and loop wait
std::cin.get();
// close
for ( int i = 0; i < Streams.size(); i++ )
{
g_Transcoder.ReleaseStream(Streams[i]);
}
g_Transcoder.Close();
// done
return 0;
}

103
ambedtest/main.h Normal file
View File

@ -0,0 +1,103 @@
//
// main.h
// ambedtest
//
// Created by Jean-Luc Deltombe (LX3JL) on 31/10/2015.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
//
// xlxd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// xlxd 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#ifndef main_h
#define main_h
#include <vector>
#include <array>
#include <map>
#include <queue>
#include <chrono>
#include <thread>
#include <mutex>
#include <atomic>
#include <condition_variable>
#include <ctime>
#include <cctype>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <algorithm>
#include <arpa/inet.h>
////////////////////////////////////////////////////////////////////////////////////////
// defines
// version -----------------------------------------------------
#define VERSION_MAJOR 1
#define VERSION_MINOR 0
#define VERSION_REVISION 0
// global ------------------------------------------------------
// Transcoder server --------------------------------------------
#define TRANSCODER_PORT 10100 // UDP port
#define TRANSCODER_KEEPALIVE_PERIOD 5 // in seconds
#define TRANSCODER_KEEPALIVE_TIMEOUT 30 // in seconds
#define TRANSCODER_AMBEPACKET_TIMEOUT 400 // in ms
// codec --------------------------------------------------------
#define CODEC_NONE 0
#define CODEC_AMBEPLUS 1 // DStar
#define CODEC_AMBE2PLUS 2 // DMR
// system constants ---------------------------------------------
////////////////////////////////////////////////////////////////////////////////////////
// typedefs
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned int uint;
////////////////////////////////////////////////////////////////////////////////////////
// macros
#define MIN(a,b) ((a) < (b))?(a):(b)
#define MAX(a,b) ((a) > (b))?(a):(b)
#define MAKEWORD(low, high) ((uint16)(((uint8)(low)) | (((uint16)((uint8)(high))) << 8)))
#define MAKEDWORD(low, high) ((uint32)(((uint16)(low)) | (((uint32)((uint16)(high))) << 16)))
#define LOBYTE(w) ((uint8)(uint16)(w & 0x00FF))
#define HIBYTE(w) ((uint8)((((uint16)(w)) >> 8) & 0xFF))
#define LOWORD(dw) ((uint16)(uint32)(dw & 0x0000FFFF))
#define HIWORD(dw) ((uint16)((((uint32)(dw)) >> 16) & 0xFFFF))
////////////////////////////////////////////////////////////////////////////////////////
// global objects
class CTranscoder;
extern CTranscoder g_Transcoder;
////////////////////////////////////////////////////////////////////////////////////////
#endif /* main_h */

17
ambedtest/makefile Normal file
View File

@ -0,0 +1,17 @@
CC=g++
CFLAGS=-c -std=c++11 -pthread
LDFLAGS=-std=c++11 -pthread
SOURCES=$(wildcard *.cpp)
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=ambedtest
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -lftd2xx -Wl,-rpath,/usr/local/lib -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
clean:
$(RM) *.o

359
ambedtest/samples.h Normal file
View File

@ -0,0 +1,359 @@
//
// dmrtodstarsample.h
// ambedtest
//
// Created by Jean-Luc Deltombe (LX3JL) on 16/05/2017.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
//
// xlxd is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// xlxd 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#ifndef dmrtodstarsample_h
#define dmrtodstarsample_h
uint8 g_uiDmrSample[] =
{
0xFD,0xAF,0xA2,0x32,0x0D,0x69,0x75,0xEF,0x64,
0xDF,0x8F,0x80,0x10,0x2F,0x4D,0x61,0xEE,0x44,
0xDF,0x8F,0x80,0x10,0x2F,0x4D,0x61,0xEF,0x20,
0xFD,0x8D,0xA2,0x10,0x2C,0x6D,0x42,0x8F,0x44,
0xBD,0xED,0xD7,0x74,0x2A,0x05,0x96,0x8F,0x88,
0xBD,0xED,0xD7,0x74,0x2A,0x05,0xA5,0xAF,0x20,
0xBD,0xED,0xD7,0x74,0x2A,0x04,0xA5,0xBE,0x88,
0xFD,0x8D,0xA2,0x10,0x2C,0x6D,0x61,0xAE,0x44,
0xBD,0xED,0xD7,0x74,0x2A,0x05,0xA5,0xAE,0x20,
0xAD,0xED,0xC6,0x74,0x2A,0x05,0xA5,0xAE,0x88,
0xBF,0xCD,0xA7,0x72,0x41,0xFF,0x30,0x23,0xA6,
0x8C,0xFD,0x84,0x50,0x63,0xDB,0x16,0x02,0x20,
0xFF,0x8F,0xC3,0x72,0x44,0xA1,0xD7,0x42,0x08,
0xCA,0xB9,0xE7,0x54,0x44,0x69,0xF1,0x3C,0xD2,
0xC8,0xB9,0xD6,0x54,0x64,0x08,0xC2,0x4A,0x20,
0xC8,0xB9,0xC6,0x54,0x65,0x0A,0xF1,0x4A,0xE2,
0x8A,0xF9,0x83,0x72,0x01,0x06,0x45,0x2A,0x6F,
0x9B,0xE9,0x83,0x72,0x00,0x04,0x45,0x2B,0x20,
0xB9,0xE9,0xA1,0x54,0x61,0x06,0x01,0x2B,0x6E,
0xBB,0xE9,0x83,0x50,0x01,0x22,0x21,0x0B,0x6E,
0xBB,0xE9,0x83,0x50,0x01,0x20,0x00,0x2B,0x20,
0xBB,0xE9,0x93,0x50,0x00,0x22,0x01,0x2B,0x6E,
0xB9,0xE9,0xA1,0x54,0x60,0x06,0x01,0x2B,0x6E,
0x99,0xE9,0x83,0x74,0x41,0x37,0x00,0x2B,0x20,
0x99,0xEB,0x83,0x52,0x45,0x57,0x15,0x2B,0x6A,
0x99,0xEB,0x83,0x52,0x45,0x57,0x14,0x2B,0x6A,
0x99,0xEA,0x83,0x52,0x45,0x57,0x14,0x29,0x20,
0x99,0xEA,0x83,0x52,0x45,0x57,0x14,0x2B,0x7B,
0xFB,0xAB,0xC4,0x76,0x42,0x0C,0xD1,0x2E,0xE2,
0x91,0xD2,0xE2,0xE5,0x03,0x16,0x1A,0xD5,0x1C,
0x6C,0x15,0xAD,0x96,0x64,0x55,0xC9,0xD3,0xA7,
0xFD,0xAE,0xC0,0x30,0x66,0xD2,0xD1,0x76,0x09,
0xD0,0x52,0xE5,0x16,0xEF,0xDF,0xA3,0x5F,0x20,
0xE6,0x8E,0x2D,0xA8,0xEF,0x80,0x33,0x82,0x9B,
0xD3,0xAA,0x1B,0xDC,0x8D,0x48,0x33,0x9E,0x72,
0xA4,0x0A,0x00,0x21,0x8D,0x55,0xF8,0x22,0x20,
0xA6,0x1A,0x23,0x64,0x9B,0x55,0xCB,0x13,0xF7,
0xC2,0x36,0x20,0x77,0xEF,0x34,0xB4,0xB8,0x46,
0x82,0x47,0x24,0x67,0xC7,0x90,0xE4,0x70,0x20,
0x78,0xFA,0x0D,0x11,0x4A,0x44,0xE5,0x2B,0xAA,
0x08,0xDF,0x2A,0x5E,0x34,0xF9,0x54,0x19,0x9F,
0xDF,0x2E,0x2E,0xE9,0x78,0x38,0x09,0xEB,0x20,
0xBC,0x7D,0x29,0xAB,0x72,0xA9,0x1A,0x05,0x55,
0xC1,0xBE,0xE3,0x77,0x22,0xEC,0x0C,0xD3,0x90,
0xC7,0xE3,0xA7,0x17,0x15,0xF0,0x81,0x3C,0x84,
0xF4,0x40,0xC2,0x73,0x32,0xBB,0xBF,0x80,0x0F,
0x4E,0xFF,0xA5,0x46,0x45,0x44,0xDB,0x7F,0x41,
0x2C,0xAE,0xE0,0x61,0x60,0x28,0x0E,0x3B,0x1C,
0xB7,0xC1,0x95,0xD4,0xA6,0x9F,0xE3,0xC1,0x01,
0x26,0x61,0xFF,0x84,0x11,0xBC,0x81,0x0F,0x7B,
0xD2,0x74,0xC8,0xD2,0x77,0xBB,0x6D,0x1B,0x20,
0x95,0x49,0xC7,0x27,0x02,0x40,0xB7,0x00,0x10,
0xE4,0xAB,0xE4,0x12,0x15,0x24,0x5D,0xFB,0x2F,
0xF3,0x30,0xDC,0x32,0x11,0xDD,0x76,0x8D,0x24,
0xE8,0x9A,0xE6,0x76,0x66,0x7B,0x85,0x0B,0xC1,
0xEA,0xB8,0xC6,0x54,0x60,0x6B,0x85,0x0B,0xE3,
0xEA,0xB8,0xC6,0x54,0x60,0x7B,0x85,0x09,0x20,
0xE9,0xAA,0xC4,0x76,0x61,0x5D,0x94,0x09,0xE7,
0xE9,0xAA,0xC4,0x76,0x61,0x5D,0x94,0x09,0xE7,
0xBA,0x7C,0x88,0xD7,0xC0,0x97,0x65,0x08,0x20,
0x92,0xB2,0x3E,0xCE,0xEC,0xF6,0x49,0x2A,0x69,
0xB0,0xF7,0x61,0x04,0x80,0xB9,0xBC,0xC9,0x26,
0x94,0xD0,0x44,0x40,0x96,0x22,0x8C,0xE0,0x20,
0x96,0xB4,0x61,0xC2,0xB3,0x33,0xF1,0x44,0x10,
0xA4,0x93,0x61,0xA0,0x39,0xDE,0xD8,0xA3,0xE7,
0x96,0xB0,0x45,0x6E,0x3C,0x90,0x64,0x98,0x20,
0x82,0xB6,0x06,0x87,0x30,0xFD,0x3D,0x01,0x46,
0xE0,0xA1,0x49,0xD4,0x33,0x4E,0x75,0x65,0xB7,
0xE6,0xB5,0x4F,0xD4,0x15,0xF1,0x20,0x4D,0x20,
0xD4,0xB6,0x4C,0xF6,0x33,0xE5,0x10,0x19,0x1E,
0xE4,0xD7,0x2C,0xDB,0x80,0x89,0x08,0xFF,0x00,
0xC7,0xE5,0x4F,0xBD,0x8B,0x52,0xFD,0x25,0x20,
0x83,0xE7,0x63,0x35,0x81,0xFA,0xBF,0x8E,0x23,
0xE5,0x82,0x21,0x33,0x95,0x5A,0x5B,0x81,0x15,
0xA1,0x8D,0x02,0x22,0xA3,0x5A,0x47,0x58,0x20,
0xE2,0x8E,0x66,0x68,0x6D,0xF2,0x4F,0x74,0x0B,
0x84,0xAF,0x12,0xCA,0x3A,0x50,0xF5,0x9F,0xE3,
0xAB,0x6A,0xE6,0x46,0x55,0x38,0x09,0x91,0x1C,
0xCC,0x56,0xE4,0x70,0x45,0x1E,0x73,0x39,0x2D,
0xDB,0x61,0xA0,0x52,0x4E,0x79,0xA2,0xD9,0xDB,
0x84,0x95,0xCE,0xE2,0x89,0xEB,0xCB,0x2E,0x1C,
0x3F,0x2C,0xDA,0x82,0x7B,0x32,0x11,0xDD,0xF2,
0xA6,0xA3,0xE0,0x00,0x67,0xE9,0x54,0x5A,0x71,
0x9B,0x21,0xD4,0x16,0x49,0x76,0x40,0xF8,0x20,
0xA5,0xB5,0x7A,0xBD,0xF4,0xC5,0x9D,0xBF,0xEB,
0xA5,0xCE,0x40,0x86,0xAC,0x3E,0xC8,0x58,0xDD,
0x90,0xAC,0x21,0x43,0xC1,0x5A,0x43,0x4F,0x1C,
0xC0,0x9E,0x66,0x5A,0x4F,0x86,0x5D,0x71,0x0E,
0x81,0x89,0x4E,0xF7,0x25,0xA4,0x08,0xF0,0xCF,
0xBB,0x23,0x6C,0xCC,0x22,0x81,0xC1,0xE8,0x20,
0x9F,0x4E,0xE0,0x03,0x36,0xD0,0x7A,0x89,0x37,
0x88,0xA3,0xC0,0x27,0x66,0xE2,0xDD,0x9C,0xFF,
0xB9,0x82,0xC2,0x45,0x04,0xE5,0xCF,0xDF,0x20,
0xD2,0x34,0xE2,0xE6,0xBF,0x9D,0xAB,0xA9,0x88,
0x97,0x6F,0x1D,0x98,0xAD,0xD2,0xDB,0x5A,0xD6,
0xC1,0x4E,0x63,0x32,0x8B,0xD4,0x0B,0x5C,0x20,
0xF0,0x7C,0x40,0x07,0xBD,0x97,0x5C,0x2C,0x95,
0x94,0x38,0x03,0x04,0xDF,0x74,0x98,0x63,0xF7,
0xB4,0x1A,0x41,0x04,0x86,0xFD,0x4C,0xBD,0x84,
0x80,0x65,0x27,0x15,0xF5,0xB1,0x94,0x31,0xF7,
0xA4,0x43,0x22,0x17,0xD0,0x7B,0xC3,0x59,0x5F,
0xC6,0x4C,0x45,0x06,0x05,0xB0,0x31,0xA3,0x20,
0xF2,0x2C,0xA6,0x32,0x51,0xE2,0x41,0x48,0x26,
0xA3,0x4E,0x1A,0xAC,0x35,0x94,0xA1,0xF5,0xDF,
0x92,0x19,0x0F,0x4C,0x65,0xB0,0x9D,0x55,0x20,
0x6F,0xD6,0xDE,0x53,0xCF,0xA2,0xF3,0x2F,0x6D,
0x8F,0x21,0x8B,0x4A,0xCF,0x6D,0x90,0x61,0xDE,
0xB8,0x00,0x5F,0xCA,0x41,0xF4,0xD5,0xDD,0x84,
0xF8,0x50,0x4A,0x8A,0x6F,0x54,0x90,0x42,0xD8,
0x14,0xED,0xA6,0x1D,0x3D,0x5F,0x90,0x85,0x51,
0xB4,0xB2,0xC2,0x35,0x55,0xAD,0x21,0x69,0x24,
0xAF,0x86,0xC4,0x31,0x35,0x3C,0xD9,0x84,0x73,
0x8F,0xB6,0xC6,0x33,0x75,0x19,0x9A,0xC0,0x02,
0x9C,0xA6,0xD5,0x53,0x55,0x7A,0xDC,0x87,0x20,
0xF9,0xA9,0xE7,0x70,0x64,0x59,0xA5,0x6B,0xF4,
0xF9,0xAB,0xE7,0x56,0x60,0x29,0x93,0x59,0xE6,
0xE9,0xA9,0xE7,0x70,0x64,0x4B,0xA4,0x68,0x1C,
0xCD,0x9D,0xE2,0x52,0x42,0xA3,0xA0,0x26,0x2C,
0xD0,0x25,0x82,0x93,0xB4,0x33,0x2F,0x73,0xF3,
0x65,0x1C,0xDD,0x05,0x73,0x26,0xB1,0x09,0x84,
0x80,0x95,0xC7,0x67,0x35,0x43,0x14,0x05,0x9D,
0xBF,0xEE,0x94,0x52,0x21,0xC9,0x34,0x24,0x92,
0xDD,0x8C,0xC1,0x52,0x00,0xA7,0xC3,0x56,0x20,
0xDD,0x8C,0xC1,0x52,0x00,0xB5,0xE0,0x76,0x7F,
0xFD,0x8C,0xC2,0x50,0x02,0xD6,0xE5,0x74,0x5B,
0xFD,0x8C,0xC2,0x50,0x02,0xD4,0xE4,0x76,0x20,
0xDD,0xAC,0xE2,0x52,0x06,0x92,0xD3,0x74,0x5B,
0xCC,0xBC,0xE2,0x52,0x06,0x92,0xD3,0x77,0x59,
0xCC,0xBC,0xE3,0x52,0x07,0x92,0xE0,0x77,0x20,
0xAC,0xAA,0x40,0x20,0x00,0x44,0x40,0x80,0x80,
0xC6,0xBE,0x1C,0xBA,0xFD,0xB0,0x31,0xB5,0x9B,
0xC4,0xBE,0x27,0xB1,0xCB,0x74,0x6B,0x1F,0x04,
0xCC,0x24,0x43,0x23,0xC5,0xD4,0xAB,0x96,0xB7,
0xDA,0x30,0x64,0x56,0x80,0x4F,0x9F,0xDD,0x0A,
0xBB,0x10,0x02,0x1F,0x4C,0xB0,0xF1,0xF4,0x20,
0xFA,0x05,0x0F,0x59,0x55,0xFC,0x5F,0x5A,0x5F,
0xAF,0x85,0xA6,0x41,0x28,0xA7,0x48,0x0C,0x09,
0xF8,0xF2,0xA5,0x15,0x13,0xAC,0x5D,0xBE,0x20,
0xEB,0xF0,0xA6,0x11,0x55,0xC9,0x7B,0xD9,0x12,
0x9A,0x82,0x82,0x17,0x78,0x09,0x3D,0x00,0xE2,
0xFD,0x2C,0x3C,0x89,0x5C,0x6E,0x09,0xCB,0x20,
0x9E,0x6D,0x29,0xE9,0x13,0xDA,0x1E,0x73,0x71,
0xAE,0x6C,0xC1,0x63,0x50,0xA1,0x5D,0xDF,0x33,
0xC6,0xBA,0xE7,0x23,0x02,0x02,0x49,0x8A,0x20,
0xB1,0x85,0xC7,0x57,0x41,0x10,0x41,0x50,0xE9,
0x5D,0xD5,0xEC,0x53,0xAA,0xD2,0xB3,0x3F,0x7F,
0x9A,0x5A,0xA5,0x66,0x59,0xA1,0x8E,0x7B,0x20,
0xFA,0x28,0x78,0xBA,0x27,0x7D,0xCD,0x59,0x06,
0x8D,0x15,0x4A,0xDF,0x05,0x19,0xF1,0x86,0x95,
0x91,0x96,0xE7,0x55,0x24,0x06,0x55,0x04,0x1C,
0x85,0x4B,0x34,0xD2,0x06,0xB9,0xDA,0x37,0xFF,
0xF5,0x2B,0x62,0xD0,0x05,0xD3,0x5F,0x36,0x21,
0xF6,0x3A,0x42,0xC1,0x33,0xD5,0x4A,0x44,0x20,
0xD2,0x0F,0x66,0xE1,0x03,0x3B,0x5C,0x4D,0xAA,
0xE6,0x6F,0x4B,0xA0,0x43,0x19,0xD1,0x55,0x7E,
0xE6,0x7D,0x5A,0xE4,0x67,0x7E,0xF5,0x56,0x20,
0xB9,0xE8,0x81,0x52,0x61,0x73,0x00,0x2A,0x6B,
0xB9,0xE8,0x81,0x52,0x61,0x73,0x00,0x2A,0x6B,
0xB9,0xE8,0x81,0x52,0x61,0x73,0x00,0x2A,0x20,
0xB9,0xE8,0x81,0x52,0x61,0x73,0x00,0x2A,0x6B,
0xB9,0xE8,0x81,0x52,0x61,0x73,0x00,0x2A,0x6B,
};
uint8 g_uiDstarSample[] =
{
0x67,0xE4,0x04,0x42,0x22,0x0F,0xE5,0x95,0xB6,
0x5E,0x84,0x1E,0x52,0xC6,0x0D,0x1C,0xD6,0x08,
0x6A,0xC5,0x12,0x5A,0x85,0x89,0x10,0x56,0x02,
0x72,0xA7,0x16,0x62,0x84,0x03,0x04,0xF6,0x0E,
0x1E,0x26,0x1A,0x03,0x43,0x8D,0x68,0xE3,0xB4,
0x6E,0xA4,0x9A,0x5A,0xE4,0x0A,0x18,0x74,0x0E,
0x02,0xA4,0x14,0x3B,0x03,0x0E,0x40,0xB1,0x32,
0x6A,0xE6,0x90,0x62,0xC5,0x8D,0x20,0x94,0x46,
0x62,0xC5,0x12,0x7A,0x66,0x08,0x18,0x06,0x8C,
0x2E,0xC5,0x12,0x23,0x62,0x02,0x54,0xA1,0xBC,
0x7A,0xC4,0x12,0x7A,0x84,0x00,0x08,0xD7,0x42,
0x6A,0x84,0x12,0x42,0xC7,0x89,0x00,0x26,0xC4,
0x1A,0xC4,0x14,0x23,0xA3,0x85,0x4C,0x20,0x7A,
0x0E,0x27,0x90,0x03,0x22,0x09,0x48,0xC2,0xF4,
0x3A,0x66,0x92,0x2B,0x21,0x8E,0x6C,0x73,0xF0,
0x6A,0xE5,0x14,0x72,0x66,0x04,0x00,0x97,0x42,
0x1E,0x47,0x90,0x3B,0x23,0x80,0x70,0x81,0xBC,
0x6E,0x86,0x18,0x52,0xC4,0x85,0x24,0x26,0x84,
0x46,0xE7,0x16,0x6A,0xE5,0x05,0x0C,0xB6,0xC8,
0xAC,0x47,0xBC,0x00,0x45,0x06,0x54,0x27,0x6E,
0xC8,0xA7,0x3A,0x79,0x61,0x80,0x0C,0xC2,0x5A,
0x76,0xA7,0x1E,0x5A,0x84,0x04,0x20,0xB5,0x0E,
0xC8,0x05,0xBC,0x49,0x01,0x83,0x10,0x41,0x56,
0xB0,0x26,0x30,0x20,0xE6,0x00,0x40,0x06,0xAE,
0x66,0xA7,0x1E,0x4A,0x87,0x05,0x0C,0x26,0x0C,
0xD1,0x29,0xAE,0x11,0x02,0x00,0x38,0x05,0x66,
0x1E,0xC4,0x12,0x33,0x03,0x05,0x78,0x23,0x72,
0x7A,0x47,0x18,0x5A,0x46,0x8C,0x38,0x06,0xC6,
0xB8,0x05,0xB4,0x28,0x05,0x02,0x74,0xF6,0xE8,
0x02,0xE4,0x12,0x23,0xE0,0x80,0x60,0xF1,0x36,
0x12,0x64,0x1C,0x13,0x22,0x0A,0x74,0x32,0xB2,
0x2E,0xE6,0x94,0x1B,0x22,0x0B,0x74,0xF2,0xF4,
0x5E,0xC7,0x9C,0x5A,0xC4,0x89,0x2C,0x17,0xC4,
0x9D,0xE6,0xBC,0xA9,0x85,0xA0,0xFD,0xCD,0xB2,
0x8E,0x56,0x02,0x69,0x7F,0x8A,0xF7,0x6A,0x0B,
0xE0,0x6B,0x9E,0x13,0xC8,0xFE,0x22,0x45,0xAD,
0xA9,0x00,0x8C,0xAA,0xBD,0x78,0x03,0xBB,0x90,
0xA8,0xB7,0x7F,0xE6,0xF9,0xA6,0x32,0x28,0xD9,
0xF1,0x55,0xFD,0xF5,0xFB,0xAA,0x6B,0x51,0xFA,
0xBC,0xF1,0xF1,0x46,0x8A,0x6F,0x7B,0xB7,0x2A,
0xED,0x34,0x4D,0xF6,0x4D,0xAC,0x28,0xCF,0xC9,
0xA0,0x74,0xC6,0xB0,0x4F,0x83,0x1E,0x39,0xE6,
0x9C,0xD4,0x92,0xA1,0x15,0xBC,0xA2,0xB7,0xA1,
0xEB,0x90,0x18,0xE0,0x55,0x23,0x96,0x45,0xC3,
0xD3,0x10,0xB0,0x92,0x13,0xF4,0xC8,0x52,0x8A,
0xD0,0x4B,0x8C,0x63,0x00,0x28,0xF1,0x66,0x27,
0x5A,0xA6,0x12,0x03,0x47,0x66,0x7B,0x89,0x42,
0x5F,0xC3,0x90,0x1A,0x35,0xC6,0xB3,0x8F,0x62,
0x52,0xC7,0x92,0x4A,0xF7,0x47,0x2C,0xD4,0x42,
0x3B,0xE2,0x8C,0x2A,0x40,0x12,0xC2,0x62,0xA4,
0x6B,0xA2,0x1C,0x43,0xE6,0xEA,0xE0,0xC3,0x2A,
0xEA,0x27,0x14,0x9B,0xA5,0xB2,0xD0,0xE9,0xB6,
0x4F,0x82,0x90,0x3A,0xE5,0x87,0xBF,0x9E,0xE6,
0xBE,0x0F,0x92,0xF2,0x41,0x47,0x75,0x37,0x64,
0x56,0x45,0x12,0x52,0x64,0x0A,0x20,0xA6,0xCE,
0xA8,0xC9,0x04,0xF9,0x22,0x8A,0x29,0x46,0x97,
0x3A,0x07,0x02,0x52,0x01,0x19,0x75,0xC8,0x4A,
0x12,0x47,0x14,0x13,0x62,0x88,0x60,0x83,0xF6,
0xBD,0xEB,0xA0,0x70,0x26,0x89,0x50,0x23,0x94,
0x76,0x45,0x90,0x6A,0x46,0x04,0x2C,0x37,0x8C,
0xE8,0xC2,0x18,0x9B,0xC4,0x9F,0x1B,0xAA,0xA6,
0x89,0xAC,0x58,0xE1,0xE8,0x97,0x4D,0x9D,0xBF,
0xCC,0x7A,0x45,0x9D,0xEF,0x8B,0x8F,0x49,0x1E,
0xF8,0x19,0x41,0x95,0xAD,0xC9,0x8B,0x88,0x99,
0xFC,0xDF,0x43,0xA4,0x8B,0xD7,0xE0,0x5A,0xB5,
0x8C,0xBC,0xCD,0xF1,0x8F,0x5E,0xB8,0xFC,0x85,
0xDD,0x5A,0x5D,0x99,0xD8,0x4E,0x4A,0x2A,0xA9,
0x88,0x1E,0x4D,0xD6,0x9C,0x8A,0x61,0xDB,0x96,
0xB9,0x38,0xED,0x29,0x36,0xE0,0x37,0xFD,0xD8,
0x9C,0xBF,0x2C,0x20,0x67,0x8C,0xF3,0x58,0xB1,
0xF8,0xBB,0x20,0x78,0xA5,0xD8,0xF0,0xBF,0x21,
0xF5,0x18,0xB2,0x09,0x91,0xFA,0x6E,0x02,0x51,
0xC8,0x7A,0x2A,0x79,0xFE,0x1D,0x22,0xA4,0x17,
0xD1,0x9A,0x65,0x20,0x7B,0x81,0xF2,0x5C,0x51,
0xE8,0x79,0x79,0x2F,0x3C,0x54,0xF2,0xBB,0x7A,
0xE1,0xDF,0x6D,0x9C,0x3A,0x01,0x93,0xF1,0xE4,
0xB9,0x98,0x79,0xBD,0x5A,0xC4,0x81,0xCE,0x09,
0x98,0x5E,0xE9,0xA4,0x2A,0xD5,0x3B,0x3D,0x97,
0xD5,0x38,0xFF,0x87,0xD7,0xBE,0x99,0xFB,0x90,
0x17,0xE3,0x9C,0x53,0x02,0x0B,0xFB,0x1A,0x5E,
0x23,0xA3,0x0A,0x32,0x41,0x14,0xFA,0xE3,0xAE,
0xF8,0xEB,0xAA,0x71,0x4E,0x1B,0x0E,0xA4,0xD1,
0x5E,0x85,0x90,0x4B,0xAE,0x86,0xDE,0x1F,0xF2,
0x7B,0xE1,0x04,0x5A,0x0D,0x1B,0x7C,0x9C,0xE2,
0x6F,0xA5,0x12,0x62,0x02,0xF1,0xA3,0xC2,0x00,
0x6B,0x66,0x06,0x3B,0x90,0x28,0xB6,0x8A,0x32,
0xF9,0x19,0xFD,0xC8,0xCF,0x00,0xC5,0xA9,0x74,
0xC1,0x1C,0x73,0xC9,0x68,0xD4,0x82,0x5A,0x9B,
0xB4,0xDF,0xE7,0x87,0x4A,0x8B,0xEE,0xE9,0x8C,
0x9B,0x53,0xD1,0x4C,0x7D,0xDC,0x45,0xEA,0x9F,
0x93,0x57,0x0C,0x5B,0xA0,0x61,0x7F,0xD1,0x61,
0xE3,0x75,0x1C,0xB0,0x23,0x12,0xAA,0x1B,0xE9,
0x6B,0xC4,0x9C,0x0B,0x42,0x98,0xE4,0x7F,0x8A,
0x62,0xE2,0x86,0x32,0x92,0x42,0x4E,0x4C,0x92,
0x43,0xA4,0x94,0x72,0x42,0xB2,0x9B,0x03,0xCE,
0xC3,0x42,0x2A,0x11,0xBE,0x82,0xAF,0x47,0x8A,
0x90,0xFE,0x45,0x3D,0x49,0x2C,0xD5,0x2F,0xD2,
0xA8,0x5D,0x4D,0x3D,0x38,0xE9,0xC1,0x2F,0x9E,
0xB1,0x52,0x63,0xF7,0x99,0xFC,0x98,0x69,0x09,
0xC8,0x51,0xFB,0xA5,0x0A,0xEA,0xDC,0x8A,0x9D,
0xF9,0x16,0x6D,0x9C,0xEB,0xF8,0x4E,0x4A,0x86,
0xCC,0x57,0xE9,0x67,0x3B,0xA0,0x6D,0x2B,0x8F,
0x81,0xF1,0x6F,0x0F,0xDE,0xC9,0xD1,0x9A,0xDB,
0xA0,0x56,0xED,0xBE,0xD0,0xB9,0xED,0xCB,0x92,
0x9C,0x55,0xB8,0xD8,0x21,0xFA,0x0D,0xC5,0xF2,
0xC4,0xF3,0xEE,0x3A,0x07,0x57,0xAF,0x0F,0x13,
0x2F,0x22,0x12,0x3A,0x33,0x68,0xA0,0x46,0x10,
0x8D,0xA0,0x2A,0x1B,0x9C,0x05,0xD1,0x6B,0x10,
0x1E,0x84,0x0A,0x5B,0xC8,0x5F,0xAB,0x82,0xBE,
0xEA,0x03,0x32,0x69,0x32,0xE2,0xEB,0x33,0xC3,
0x2F,0xA6,0x1A,0x13,0xE5,0xFE,0xDB,0x24,0xFE,
0x73,0xE3,0x1C,0x63,0x16,0xEA,0xEC,0xE2,0xEE,
0x6A,0xC4,0x12,0x33,0x95,0x26,0x57,0x28,0x82,
0xB9,0x24,0x78,0x51,0xE1,0x15,0xB0,0xCF,0xE1,
0xE0,0x85,0x32,0x61,0x23,0x0E,0x00,0x91,0x90,
0x5A,0x46,0x12,0x72,0xA4,0x80,0x38,0xF6,0xCE,
0xBD,0x8B,0x04,0x9B,0x84,0x07,0x24,0xBB,0x48,
0x6E,0x25,0x18,0x52,0xC4,0x02,0x24,0xB4,0x8A,
0x92,0x42,0x14,0x91,0x45,0x18,0x71,0x94,0xB4,
0xD9,0x6C,0x9E,0x9A,0x86,0x86,0x2A,0x36,0xA0,
0xEA,0x8C,0x02,0x02,0xE1,0xEE,0x79,0x7B,0xFB,
0x7E,0x65,0x0C,0x13,0x24,0x9A,0x1D,0xBF,0xBE,
0x42,0x85,0x18,0x72,0x65,0x0E,0x14,0x05,0xCE,
0x5E,0xA5,0x16,0x72,0x45,0x00,0x3C,0x55,0x8A,
0xB9,0x0B,0xAA,0x48,0x86,0x8A,0x40,0xE0,0x9C,
0xC5,0x49,0xA0,0x31,0x00,0x07,0x00,0xA5,0x6A,
0x7E,0xC4,0x10,0x72,0xA4,0x80,0x08,0xC7,0xC2,
0x0A,0x47,0x12,0x03,0x81,0x00,0x6C,0xC0,0xFE,
0x1A,0xC7,0x9E,0x03,0xE0,0x81,0x68,0xA0,0xB4,
0x06,0xC5,0x10,0x33,0x63,0x88,0x60,0x31,0xB6,
0x1A,0xE4,0x1A,0x13,0xE1,0x0E,0x4C,0x50,0xB8,
0x9A,0xA1,0xC8,0x28,0xE0,0x72,0x0D,0xAE,0xD8,
0x92,0x30,0xC9,0x7B,0x5B,0x4F,0x5D,0x6D,0xBE,
0xCE,0x94,0xD9,0xC8,0xDF,0x4F,0xAC,0xC8,0x12,
0xCB,0x13,0xCF,0xE6,0x4C,0x8C,0xEB,0x6F,0xD7,
0xEB,0x17,0xE5,0x10,0x9B,0xD6,0xE8,0xC4,0xAF,
0x8B,0xD1,0xAC,0x7B,0xCA,0x5F,0x12,0xA4,0xAF,
0x8E,0xD3,0xA2,0x71,0x95,0xF8,0x8E,0x7E,0xCA,
0x3B,0x44,0x1C,0x23,0x75,0xFE,0xDF,0xD5,0x7A,
0x33,0x43,0x96,0x32,0x30,0xE4,0xB0,0xA6,0x96,
0x4F,0xE1,0x18,0x63,0xB6,0x26,0xD8,0xE1,0x6A,
0x6F,0xC7,0x16,0x62,0xE3,0xFA,0x97,0x91,0x82,
0xF1,0xC7,0x8C,0xFB,0x86,0xE3,0xCE,0x75,0xB2,
0xA3,0x92,0x38,0xDB,0x45,0xF8,0x88,0x75,0xBE,
0x02,0xE3,0x16,0x5B,0x46,0xBC,0x5C,0x2D,0xDC,
0xBE,0xB6,0x80,0xF9,0x03,0x90,0x2B,0x3C,0x26,
0xF8,0x2A,0x3C,0x29,0x95,0x42,0xF9,0xA4,0xDE,
0xC4,0x42,0x32,0xA3,0x21,0xBA,0xEF,0x07,0xB2,
0xE8,0x88,0xBC,0x58,0xC5,0xAB,0xAE,0x8B,0xD6,
0x0F,0x00,0x1E,0x63,0x23,0x86,0xCF,0xCB,0x9A,
0xBB,0xF1,0x2E,0xD8,0xA7,0x58,0x07,0x86,0xDB,
0xFD,0x0A,0x94,0xBB,0xE0,0x15,0x4D,0xD4,0x06,
0xE1,0xB7,0xA3,0xDB,0x00,0x43,0x2A,0x5A,0xEB,
0xF4,0x99,0x40,0x31,0xD0,0x1D,0x7B,0xDD,0x72,
0xA5,0xD4,0x65,0x92,0x84,0xCF,0x7A,0x2F,0xD5,
0x89,0x4A,0x80,0x9B,0xF5,0xC6,0x0C,0xAA,0x84,
0x88,0x30,0xF8,0xB0,0xB5,0xC5,0x19,0x48,0x1A,
0xFC,0xE5,0x3C,0x59,0x41,0x03,0x28,0xF2,0x9C,
0x99,0xC9,0x26,0x58,0xE6,0x09,0x6C,0x61,0xD8,
0x99,0xE8,0xAA,0x78,0x85,0x0F,0x64,0x32,0x92,
0x5E,0xC7,0x18,0x52,0xC4,0x05,0x3C,0xA6,0x8A,
0x0E,0xC4,0x94,0x3B,0x22,0x03,0x60,0x60,0x70,
};
#endif /* dmrtodstarsample_h */