Archive pour la catégorie ‘C/C++’

Bluid minimal ffmpeg on raspberrypi

Lundi 14 décembre 2020

If you have a minimalist raspian system and you want to install ffmpeg, with the command apt install ffmpeg you will find yourself in front of a huge list of dependencies, and more than 700MB of downloads.
Why not choose to compile a minimalist ffmpeg that will meet your needs:

Download source file:
wget -O ffmpeg-snapshot.tar.bz2 https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz

Extract file content:
tar xvjf ffmpeg-snapshot.tar.bz2

Run configure script
./configure --extra-libs="-lpthread -lm -latomic"

Now, build
make -j4

Check version

user@raspberrypi:~/ffmpeg/ffmpeg $ ./ffmpeg -version
ffmpeg version N-100408-g081a179 Copyright (c) 2000-2020 the FFmpeg developers
built with gcc 8 (Raspbian 8.3.0-6+rpi1)
configuration: --extra-libs='-lpthread -lm -latomic'
libavutil 56. 62.100 / 56. 62.100
libavcodec 58.115.102 / 58.115.102
libavformat 58. 65.100 / 58. 65.100
libavdevice 58. 11.103 / 58. 11.103
libavfilter 7. 93.100 / 7. 93.100
libswscale 5. 8.100 / 5. 8.100
libswresample 3. 8.100 / 3. 8.100
user@raspberrypi:~/ffmpeg/ffmpeg $ ldd ./ffmpeg
linux-vdso.so.1 (0x7ecc4000)
/usr/lib/arm-linux-gnueabihf/libarmmem-${PLATFORM}.so => /usr/lib/arm-linux-gnueabihf/libarmmem-v7l.so (0x76ec7000)
libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0x76e45000)
libz.so.1 => /lib/arm-linux-gnueabihf/libz.so.1 (0x76e1a000)
libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0x76df0000)
libatomic.so.1 => /usr/lib/arm-linux-gnueabihf/libatomic.so.1 (0x76dd7000)
libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x76c89000)
/lib/ld-linux-armhf.so.3 (0x76edc000)

Use it to download snapshot from network camera:
./ffmpeg -i rtsp://192.168.1.17:554/user=admin_password=tlJwpbo6_channel=0_stream=0.sdp?real_stream -vframes 1 -r 1 -vframes 1 -r 1 output.jpeg

http://themadmax.free.fr/blog/wp-content/ffmpeg.bz2

Add VBScript into C++ Application

Mardi 16 juin 2015

How to add Scripting possibility, under windows with VBScript.

[sourcecode language="cpp"]
#include <windows.h>
#include <OleAuto.h>
#include <stdio.h>
#include <comutil.h>
#pragma comment (lib, "OleAut32.lib")
#pragma comment (lib, "comsuppw.lib")

#import "msscript.ocx"

MSScriptControl::IScriptProcedurePtr GetScriptFunction(MSScriptControl::IScriptControlPtr pScript, LPCTSTR szName)
{
MSScriptControl::IScriptProcedureCollectionPtr pIProcedures = pScript->GetProcedures();
long count = pIProcedures->GetCount();
for(long index=1; index <= count; index++)
{
MSScriptControl::IScriptProcedurePtr pIProcPtr = pIProcedures->GetItem( _variant_t(index) );
_bstr_t name = pIProcPtr->GetName();
if ( lstrcmp( name, szName ) == 0 )
return pIProcPtr ;
pIProcPtr = NULL;
}
return NULL ;
}

void create_script()
{
CoInitialize(NULL);
MSScriptControl::IScriptControlPtr m_pScript ;
HRESULT hr = m_pScript.CreateInstance(__uuidof(MSScriptControl::ScriptControl));

m_pScript->PutAllowUI( VARIANT_TRUE );
m_pScript->PutLanguage( _bstr_t(L"VBScript") );

_variant_t obj(1.2345);

wchar_t code[] = L"Function Toto()\nToto = 1.2345\nEnd Function" ;
hr = m_pScript->AddCode( _bstr_t(code) );

MSScriptControl::IScriptProcedurePtr pFunc = GetScriptFunction(m_pScript,L"Toto");

SAFEARRAY *parameters = ::SafeArrayCreateVector( VT_VARIANT, 0, 0 );

_variant_t ret = m_pScript->Run( _bstr_t("Toto"), &parameters );

_bstr_t bv(ret);
wprintf(L"%s\n", bv.GetBSTR());
}

int main(int argc, char** argv)
{
create_script();
}
[/sourcecode]

Compilation de FFMPEG sous Windows 32bit LGPL

Mercredi 13 août 2014

Ce n’est pas le plus facile a faire : compiler FFMPEG sous windows malgres les documentation trouver en ligne:

https://www.ffmpeg.org/platform.html#Microsoft-Visual-C_002b_002b-or-Intel-C_002b_002b-Compiler-for-Windows
http://ffmpeg.zeranoe.com/forum/viewtopic.php?f=5&t=1309

Voila la commande utilise pour la configuration:
# ./configure –toolchain=msvc –enable-shared –yasmexe=vsyasm.exe –cpu=i686 –prefix=ffmpeg/

FFMPEG 2.1.4 WIN32 LGPL

VBScript passage de tableau par reference

Jeudi 27 mars 2014

Comment faire communiquer un Object COM en C++ avec un VBScript :

IDL :
[sourcecode]
library EngineLib
{
dispinterface _IEngineEvents
{
[id(27)] HRESULT MyCallBack( [in,out] VARIANT* arr);
}
}
[/sourcecode]
Le code de l’objet COM C++:
[sourcecode language="cpp"]SAFEARRAY *pSafeArray = ::SafeArrayCreateVector( VT_VARIANT, 0, 1 );
LONG indices = 0 ;
_variant_t v0(L"Hello");
::SafeArrayPutElement( pSafeArray, &indices, &v0 );
VARIANT variant;

VariantInit( &variant );
variant.pparray = &pSafeArray;
variant.vt = VT_BYREF|VT_ARRAY|VT_VARIANT;

CComVariant pVars[1] ;
pVars[0].pvarVal = &variant;
pVars[0].vt = VT_BYREF|VT_VARIANT;

fire( pVars, 1, 27 );
[/sourcecode]
La Fonction fire:
[sourcecode language="cpp"]void fire( CComVariant* pVars, int size, int invoke )
{
CComVariant varResult;
int s = ConnectionPoint.GetSize();
for (int nConnectionIndex=0;nConnectionIndex<s; nConnectionIndex++)
{
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
EXCEPINFO excepinfo ;
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if ( pDispatch )
{
VariantClear(&varResult);
DISPPARAMS disp = { pVars, NULL, size, 0 };
HRESULT hr = pDispatch->Invoke( invoke, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, &excepinfo, NULL);
}
}
}[/sourcecode]
Le code VBScript:
[sourcecode language="vb"]Function IEngineEvents_MyCallBack( ByRef arr ) ‘Function name is very important
WScript.Echo "arr=" & arr(0)
ReDim Preserve arr(UBound(arr) + 1)
arr(0) = "A1"
arr(1) = "A2"
End Function

Set engine = WScript.CreateObject("MyComComponent", "IEngineEvents_")
‘This function call MyCallBack indirectly
engine.CallCallBack
[/sourcecode]

Programmer une extention Python

Mercredi 12 mars 2014

Comment faire une extension python27 avec Visual Studio 2008 :
Installer python27: http://www.python.org/download/releases/2.7/
Dans visual studio créer une solution DLL, en Release. En Debug, on doit lier avec python27_d.lib, qui ne se trouve pas dans la distribution standard.
Puis copier la dll dans le repertoire de python c:\python27, changer l’extension de la DLL en pyd.
lancer l’invite de commande python, (attention si elle est deja lancer il faut relancer). Puis tapper
>>> import extend
>>> extend.system("dir")

Attention les noms des fichiers, et l’export de la fonction dans le .def doivent correspondre.

Voici le code :
[sourcecode language="cpp"]//#define MS_NO_COREDLL
#include <Python.h>

static PyObject *SpamError;

static PyObject *
spam_system(PyObject *self, PyObject *args)
{
const char *command;
int sts;

if (!PyArg_ParseTuple(args, "s", &command))
return NULL;
sts = system(command);
return Py_BuildValue("i", sts);
}

static PyMethodDef SpamMethods[] = {
{"system", spam_system, METH_VARARGS,"Execute a shell command."},
{NULL, NULL, 0, NULL} /* Sentinel */
};

PyMODINIT_FUNC
initextend(void)
{
PyObject *m;

m = Py_InitModule("extend", SpamMethods);
if (m == NULL)
return;

SpamError = PyErr_NewException("extend.error", NULL, NULL);
Py_INCREF(SpamError);
PyModule_AddObject(m, "error", SpamError);
}[/sourcecode]

Fichier source et solution

Playing with Usb

Jeudi 6 mars 2014

I have an Usb device with led notifier (1294:1320). The device use HID interface, under linux you can use libusb to communicate with, but under windows it more complicated.

This is my sample code to change usb device led status:

Source UsbNotifier.zip

[sourcecode language="cpp"]#include <windows.h>
#include <setupapi.h>
#include <stdio.h>

const GUID GUID_DEVINTERFACE_HID = {0x4d1e55b2, 0xf16f, 0x11cf, {0×88, 0xcb, 0×00, 0×11, 0×11, 0×00, 0×00, 0×30} };

typedef struct _HIDD_ATTRIBUTES {
ULONG Size; // = sizeof (struct _HIDD_ATTRIBUTES)
USHORT VendorID;
USHORT ProductID;
USHORT VersionNumber;
} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;

extern "C" {
BOOLEAN __stdcall
HidD_GetAttributes (
__in HANDLE HidDeviceObject,
__out PHIDD_ATTRIBUTES Attributes
);
}

HANDLE find( USHORT VendorID, USHORT ProductID )
{
HANDLE write_handle ;
HDEVINFO device_info_set = SetupDiGetClassDevs( &GUID_DEVINTERFACE_HID,
NULL,
NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
int device_index = 0;
SP_DEVICE_INTERFACE_DATA device_interface_data;
SP_DEVICE_INTERFACE_DETAIL_DATA* device_interface_detail_data ;
memset( &device_interface_data, 0, sizeof(device_interface_data) );
device_interface_data.cbSize = sizeof(device_interface_data);

for(;;device_index++)
{
DWORD required_size = 0;
BOOL res;
HIDD_ATTRIBUTES attrib;
res = SetupDiEnumDeviceInterfaces(device_info_set,
NULL,
&GUID_DEVINTERFACE_HID,
device_index,
&device_interface_data);
if ( !res) {
break;
}

res = SetupDiGetDeviceInterfaceDetail(device_info_set,
&device_interface_data,
NULL,
0,
&required_size,
NULL);

device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA*) malloc(required_size);
device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

res = SetupDiGetDeviceInterfaceDetail(device_info_set,
&device_interface_data,
device_interface_detail_data,
required_size,
NULL,
NULL);

write_handle = CreateFile(device_interface_detail_data->DevicePath,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
//FILE_FLAG_OVERLAPPED,
FILE_ATTRIBUTE_NORMAL,
NULL);

if (write_handle == INVALID_HANDLE_VALUE) {
continue ;
}

attrib.Size = sizeof(HIDD_ATTRIBUTES);
HidD_GetAttributes(write_handle, &attrib);
if ( attrib.VendorID == VendorID && attrib.ProductID == ProductID )
return write_handle ;
else
CloseHandle( write_handle );
}
return INVALID_HANDLE_VALUE ;
}

//write_handle = find( 0×1294, 0×1320 );
int hid_write( USHORT VendorID, USHORT ProductID, size_t size, char value )
{
DWORD dwErr ;
int device_index = 0;
HANDLE write_handle = INVALID_HANDLE_VALUE;
HIDD_ATTRIBUTES attrib;

//printf("DevicePath : %s\n" , DevicePath );

write_handle = find( VendorID, ProductID );

if (write_handle == INVALID_HANDLE_VALUE) {
printf("Unable to open err=0x%x\n", GetLastError() );
return 1 ;
}

attrib.Size = sizeof(HIDD_ATTRIBUTES);
HidD_GetAttributes(write_handle, &attrib);

//wprintf(L"Product/Vendor: %04x %04x\n", attrib.ProductID, attrib.VendorID);

{
BOOL ret ;
BYTE *buff = (BYTE*)malloc( size );
DWORD written = 0 ;
memset( buff, 0, size );
buff[1] = value ;

ret = WriteFile( write_handle, buff, 6, &written, NULL );
if ( ret == FALSE ) {
dwErr = GetLastError();
return dwErr ;
}
}

CloseHandle( write_handle );
return 0;
}

int main( int argc, char** argv )
{
if ( argc < 2 )
return -1 ;
char c = argv[1][0];
c -= ’0′ ;
hid_write( 0×1294, 0×1320, 6, c );
}[/sourcecode]

Gcc et Nasm en 64bit

Samedi 21 décembre 2013

Voici un petit exemple pour creer une fonction en assembleur avec NASM, et ensuit l’utiliser dans un programme C. Attention les convention de passage d’argument en 64bit ne sont plus les meme que pour du 32bits.
Fichier add.asm
global myfunction
section .text

myfunction:
mov eax, edi
mov ecx, esi
add eax, ecx
ret

Fichier test.c
#include

extern int myfunction(int a,int b);

int main()
{
printf("sum=%d\n", myfunction(12,3));
}

Pour compiler :
gcc -c test.c; nasm -f elf64 add.asm; gcc -o add test.o add.o
Le code source: asm

Factory en C++

Jeudi 23 mai 2013

Voici un petit bout de code pour faire une factory en C++:
[sourcecode language="cpp"]
#include <string>
#include <map>
#include <algorithm>

class Base {
std::string _type ;
public:
Base(const std::string& type = "base") : _type(type) {}
};
class A : public Base {
public:
A(const std::string& type = "A") : Base(type) {}
};
class B : public Base {
public:
B(const std::string& type = "B") : Base(type) {}
};

template<class T>
class Factory
{
typedef T* (*Creator)();
std::map<std::string,Creator> _map ;
public:
T* create(const std::string& type)
{
return _map[type]();
}
void record(const std::string& type, Creator func)
{
_map[type] = func ;
}
template<class U>
static T* creator() { return new U(); }
};

void testFactory()
{
Factory<Base> factory;
factory.record( "A", &(Factory<Base>::creator<A>) );
factory.record( "B", &Factory<Base>::creator<B> );
Base* a = factory.create("A");
Base* b = factory.create("B");
}
[/sourcecode]

Visual Studio CppUnit Wizard Template

Mardi 17 avril 2012

Extraire le zip dans le repertoire C:\Program Files\Microsoft Visual Studio 9.0\VC\VCWizards
CppUnitWizard.zip
Dans le repertoire C:\Program Files\Microsoft Visual Studio 9.0\VC\VCAddClass
Creer un fichier CppUnitTest.vsz avec le contenu :

VSWIZARD 7.0
Wizard=VsWizard.VsWizardEngine.9.0
Param= »WIZARD_NAME = CppUnit »
Param= »WIZARD_UI = TRUE »

Après dans un project C++ clique droit sur le project > Add > Class… > Sélectionner Visual C++ puis CppUnitTest

C++ surcharge de l’opérateur de comparaison

Jeudi 24 novembre 2011

Le langage C++ permet de surchargé les opérateurs ce qui permet de faire des opérations comme la comparaison entre des objets.

De plus comme la STL est bien implémenté il est possible aussi d’utilisé dans des conteneurs l’appel à la surcharge de l’opérateur de comparaison.

Comme d’habitude un exemple vaut mieux qu’un long discourt:

[sourcecode language="cpp"]#include <vector>
#include <iostream>

using namespace std ;

class A
{
int _a ;
public:
A( int a ) : _a(a) {}
virtual bool operator==(const A& p) const
{
return ( _a == p._a );
}
};

class B : public A
{
float _b ;
public:
B( int a, float b ) : A(a), _b(b) {}
virtual bool operator==(const A& p) const
{
if ( A::operator ==(p) != true )
return false ;
const B& pp = dynamic_cast<const B&>(p);
return ( _b == pp._b );
}
};

template<class T>
void print( const char* text, const T& p1, const T& p2 )
{
cout << text ;
try
{
if ( p1 == p2 )
cout << " => true" ;
else
cout << " => false" ;
} catch (…)
{
cout << " => Exception" ;
}
cout << endl;
}

int main()
{
B b1( 1, 1.1f );
B b2( 1, 1.1f );
print( "b1( 1, 1.1 ) == b2( 1, 1.1 )", b1, b2 );
B b3( 1, 1.2f );
print( "b1( 1, 1.1 ) == b3( 1, 1.2 )", b1, b3);
print( "b3( 1, 1.2 ) == b3( 1, 1.1 )", b3, b1);
A a1( 1 );
print<A>( "a1( 1 ) == b1( 1, 1.1 )", a1, b1 );
print<A>( "b1( 1, 1.1 ) == a1( 1 )", b1, a1 );

vector<B> vb1;
vb1.push_back( b1 );
vb1.push_back( b2 );
vb1.push_back( b3 );

vector<B> vb2;
vb2.push_back( b1 );
vb2.push_back( b2 );
vb2.push_back( b3 );

print("vb1 == vb2", vb1, vb2 );
print("vb2 == vb1", vb2, vb1 );

vb1[0] = b3 ;
print("vb1 == vb2", vb1, vb2 );
}[/sourcecode]

Sortie console :
[code]b1( 1, 1.1 ) == b2( 1, 1.1 ) => true
b1( 1, 1.1 ) == b3( 1, 1.2 ) => false
b3( 1, 1.2 ) == b3( 1, 1.1 ) => false
a1( 1 ) == b1( 1, 1.1 ) => true
b1( 1, 1.1 ) == a1( 1 ) => Exception
vb1 == vb2 => true
vb2 == vb1 => true
vb1 == vb2 => false[/code]