Good Morning
I'm implementing a distributed image normalization algorithm an I'm using Boost::mpi with a class Pixel that contain the serialization code,
#ifndef PIXEL_H
#define PIXEL_H
#include <boost/mpi.hpp>
#include <boost/serialization/access.hpp>
class Pixel
{
private:
unsigned char m_red;
unsigned char m_green;
unsigned char m_blue;
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive &ar, const unsigned int version) {
ar & m_red;
ar & m_green;
ar & m_blue;
}
public:
Pixel();
Pixel(unsigned char red,unsigned char green,unsigned char blue) : m_red(red), m_green(green), m_blue(blue) {};
virtual ~Pixel();
unsigned char getRed();
void setRed(unsigned char val);
unsigned char getGreen();
void setGreen(unsigned char val);
unsigned char getBlue();
void setBlue(unsigned char val);
void setColor (unsigned char red,unsigned char green,unsigned char blue);
};
The main.cpp is
#include <iostream>
#include <boost/mpi.hpp>
#include <vector>
#include "include/Pixel.h"
#include <cstdlib>
#include <ctime>
#define ALTEZZA 2
#define LARGHEZZA 2
namespace mpi=boost::mpi;
int main(int argc, char * argv[]) {
std::cout<<"Inizializzazione dell'ambiente MPI"<<std::endl;
mpi::environment env;
mpi::communicator world;
Pixel **vettore;
int i,j;
//Inizializzazione della matrice di test
if(world.rank() == 0){
std::cout<<"Inizializzazione matrice di test..."<<std::endl;
std::srand(std::time(0));
vettore = new Pixel *[ALTEZZA];
for (i = 0; i < ALTEZZA; i++) {
vettore[i] = new Pixel[LARGHEZZA];
}
for (i = 0; i < ALTEZZA; i++) {
for (j = 0; j < LARGHEZZA; j++) {
vettore[i][j].setColor(std::rand() % 256, std::rand() % 256, std::rand() % 256);
std::cout<<"Vettore["<<i<<"]["<<j<<"] = ("<<int(vettore[i][j].getRed())<<","<<int(vettore[i][j].getGreen())<<","<<int(vettore[i][j].getBlue())<<");"<<std::endl;
}
}
}
if (world.rank() == 0) {
std::cout<<"Invio matrice.."<<std::endl;
world.send(1, 0, vettore[0]);
}else {
Pixel *px;
world.recv(0, 0, px);
for (j = 0; j < LARGHEZZA; j++) {
std::cout<<int(px[j].getRed())<<" "<<int(px[j].getGreen())<<" "<<int(px[j].getBlue())<<std::endl;
}
}
return 0;
}
but when i run the program the cout on the receiving process print wrong value like this
Inizializzazione dell'ambiente MPI
Inizializzazione dell'ambiente MPI
Inizializzazione matrice di test...
Vettore[0][0] = (170,103,165);
Vettore[0][1] = (84,0,186);
Vettore[1][0] = (93,228,162);
Vettore[1][1] = (31,100,204);
Invio matrice..
170 103 165
217 1 0
I think that the problem is the 2d array because if I use std::vector i haven't this problem but I don't understand why.
I would imagine you have several problems (I can't test as I don't have a capable MPI installation..)
Firstly, your send() is wrong, currently you are triggering the overload:
template<typename T> void send(int, int, const T &) const;
But you are trying to send a raw array, I imagine the fix here has to be to pass the count, for example:
world.send(1, 0, vettore[0], 2); // 2 Pixels
Secondly, on the receiver side (this I'm not sure about), but I imagine you need to have a suitable array to read the data into.., for example:
Pixel px[LARGHEZZA];
world.recv(0, 0, px, 2);
I think this should fix your problems...
Related
I'm trying to create a class that saves BMP image given the pixels.
This is my .h:
#ifndef _IMAGE_SAVER_
#define _IMAGE_SAVER_
#include <vector>
#include <fstream>
#include <sstream>
#include <string>
#include <bitset>
//#define _DEBUG_
#ifdef _DEBUG_
#include <iostream>
#endif
#include <stdint.h>
typedef struct BMFileHeader {
uint16_t _bfType = 19778;
uint32_t _bfSize;
uint16_t _bfReserved1 = 0;
uint16_t _bfReserved2 = 0;
uint32_t _bfOffBits = 54;
} BMFileHeader;
typedef struct BMInfoHeader {
uint32_t _biSize = 40;
uint32_t _biWidth;
uint32_t _biHeight;
uint16_t _biPlanes = 1;
uint16_t _biBitCount = 24;
uint32_t _biCompression = 0;
uint32_t _biSizeImage = 0;
uint32_t _biXPelsPerMeter = 3780;
uint32_t _biYPelsPerMeter = 3780;
uint32_t _biClrUser = 0;
uint32_t _biClrImportant = 0;
} BMInfoHeader;
typedef struct RGBQuad {
uint8_t _blue;
uint8_t _green;
uint8_t _red;
} RGBQuad;
class ImageSaver
{
public:
ImageSaver() = delete;
ImageSaver(const uint32_t& height, const uint32_t& width, const std::vector<RGBQuad>& pixels) : _RGBQuad_Vector(pixels) {
this->_Info_Header._biHeight = height;
this->_Info_Header._biWidth = width;
};
void saveImage(const std::string& fileName);
protected:
void setFileSize();
void createImageFile(const std::string& fileName);
private:
BMFileHeader _File_Header;
BMInfoHeader _Info_Header;
std::vector<RGBQuad> _RGBQuad_Vector;
};
#endif
this is my .cpp:
#include "ImageSaver.h"
void ImageSaver::saveImage(const std::string& fileName)
{
this->setFileSize();
this->createImageFile(fileName);
}
void ImageSaver::setFileSize()
{
uint32_t height = this->_Info_Header._biHeight;
uint32_t width = this->_Info_Header._biWidth;
this->_File_Header._bfSize = 3 * (height * width) + 54;
}
void ImageSaver::createImageFile(const std::string& fileName)
{
std::ofstream imageFile(fileName + ".bmp", std::ios::binary);
imageFile.write((char*)&this->_File_Header, 14);
imageFile.write((char*)&this->_Info_Header, 40);
size_t numberOfPixels = this->_Info_Header._biHeight * this->_Info_Header._biWidth;
for (int i = 0; i < numberOfPixels; i++) {
imageFile.write((char*)&(this->_RGBQuad_Vector[i]), 3);
}
imageFile.close();
}
and this is my main.cpp:
#include "ImageSaver.h"
#include <vector>
#include <iostream>
int main() {
std::vector<RGBQuad> pixels;
for (unsigned i = 0; i < 512 * 512; i++) {
RGBQuad pixel;
pixel._blue = 0;
pixel._green = 255;
pixel._red = 255;
pixels.push_back(pixel);
}
ImageSaver im(512, 512, pixels);
im.saveImage("scene1");
std::cout << "ESTOP0" << std::endl;
return 0;
}
Whenever I try to create an image file, it says that that image file is corrupt, even though it seems to me that I've been following BMP format properly. I've analyzed raw binary data and data seems (to me) to be correct. GIMP can open the picture, but it gives a black 512x512 picture which is not what I'm going for here.
Certainly you miss #pragma pack. Wrap your structures with #pragma pack(push,1)/#pragma pack(pop)
When structures represent memory layout and should have no padding, even if having unaligned data, pack structures.
It is very helpful to have static_assert on expected sizeof value for such cases.
Additionally, when you pack them, the RGBQuad will become only 3 bytes. If you really want triple, suggest renaming it to triple. Otherwise add dummy or alpha byte to complete it to quad.
I am new at using Google Mock and I encountered an error: "Error: Actual function call count doesn't match EXPECT_CALL(…)".
I am not sure what I am doing incorrectly. I followed this solution suggested here and I am still encountering this error.
Here is the sample code I am working on:
Orig Class
//orig.h
#include <stdio.h>
class Orig {
public:
virtual ~Orig(){}
virtual int this_func(uint8_t x, uint8_t* y, uint8_t z) = 0;
virtual int that_func(uint8_t x, uint8_t* y, uint8_t z) = 0;
virtual void those_func(int abc) = 0;
};
Mock Orig Class
//mock_orig.h
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "calling_class.h"
class MockOrig : public Orig {
public:
MOCK_METHOD3(this_func, int(uint8_t x, uint8_t* y, uint8_t z));
MOCK_METHOD3(that_func, int(uint8_t x, uint8_t* y, uint8_t z));
MOCK_METHOD1(those_func, void(int abc));
};
Calling Class
//calling_class.h
#define MY_CONST1 0x01
#define MY_CONST2 0x02
#define X_CONST1 0x03
#define X_CONST2 0x04
#define SAMPLE_VALUE (20)
#define TOTAL_VALUE (100/SAMPLE_VALUE)
#include "orig.h"
class CallingClass {
public:
explicit CallingClass(Orig * o) : mOrig(o){};
void calling_func(void) {
static int oldValue = 0;
static uint16_t counter = 0;
uint8_t buffer[2] = {0};
int firstBit = 0;
int secondBit = 0;
if (0 == oldValue && (0 == mOrig->this_func(X_CONST1, buffer, 1))
{
secondBit = (int)(buffer[0] & MY_CONST2);
firstBit = (int)(buffer[0] & MY_CONST1);
if((oldValue != secondBit) && (0 != firstBit))
{
mOrig->those_func(secondBit);
oldValue = secondBit;
counter = TOTAL_VALUE;
}
return;
}
if (0 >= --counter && (0 == mOrig->this_func(X_CONST1, buffer, 1)))
{
uint8_t out = buffer[0] | MY_CONST2;
mOrig->that_func(X_CONST2, &out, 1);
oldValue = 0;
}
return;
}
private:
Orig * mOrig;
}
Test Proper
//mock_orig.cpp
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include <memory>
TEST(myTest, testMyFunction)
{
std::shared_ptr<Orig> mO(new MockOrig);
uint8_t buffer[1];
EXPECT_CALL(*std::static_pointer_cast<MockOrig>(mO), this_func(X_CONST1, buffer, 1))
.Times(1);
CallingClass callerClass(mO.get());
callerClass.calling_func();
}
int main(int argc, char **argv)
{
testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
Can somebody please tell me what is still wrong with this? Any help/leads would be greatly appreciated. thanks!
How do I pass a matrix as an argument between two function that are in different source files? (with their respective header file)
Do not worry about all the variables and arguments below.
//uex1010.cpp
typedef int Casilla;
void ejecutar(){
int tamanio, maxPuntos, numPiezas,puntActual=0;
int fila, col, color, ancho, alto;//variables
bool salir;
fila=0;
col=0;
TipoTecla tecla;
srand(time(NULL));
if (entornoCargarConfiguracion(tamanio, maxPuntos, numPiezas)) {
entornoIniciar(tamanio);
}
int i;
entornoActivarCasilla(fila, col);
salir = false;
Casilla ocupada[tamanio-1][tamanio-1];
comprobarCasilla(ocupada[tamanio-1][tamanio-1],col,fila,alto,ancho,color,tamanio);// I want to send "ocupada" to comprobarCasilla() in tablero.cpp
//............
tablero.cpp
void comprobarCasilla(Casilla &ocupada, int col, int fila, int &alto, int &ancho, int &color, int tamanio) {
int i = 0, j = 0, colaux = col, filaux = fila;
while ((i < alto) && (ocupada[fila][col] == 0)) {//HERE
col = colaux;
j = 0;
while ((j < ancho) && (ocupada[fila][col]==0)) {//HERE
col++;
j++;
}
fila++;
i++;
}
if (ocupada[fila][col]==0) {//AND HERE it returns an error
pintar(ocupada, colaux, filaux, alto, ancho, color);
}
}
The error is: tipos inválidos ‘Casilla {aka bool}[int]’ para índice de matriz
invalid types ‘Casilla {aka bool}[int]’ for matrix index
Here is the header file:
#ifndef TABLERO_H_
#define TABLERO_H_
#include "entorno.h"
#include <iostream>
#include <ctime>
#include <cstdlib>
#include "pieza.h"
typedef int Casilla;
void iniciarTablero(bool salir);
void pintar(Casilla ocupada,int col,int fila,int &alto,int &ancho,int &color);
void comprobarCasilla(Casilla &ocupada,int col,int fila,int &alto,int &ancho,int &color,int tamanio);
#endif /* TABLERO_H_ */
I'm trying to use LibVLC to decode a video file and render it to a texture.
The code for opening and start playing works, the audio plays perfectly, but the pixel buffer is always filled with 0xCD. The videos I try to render work on VLC, and even in a C# implementation I did they work, but with this new code in C I can't manage to get it working...
I'm using the x64 version of the vlc libs and the program is compiled for x64 if this makes any difference.
Here is my code:
#include "stdafx.h"
#include "video.h"
#include <string.h>
#include <vlc\libvlc.h>
#include <vlc\libvlc_media.h>
#include <vlc\libvlc_media_player.h>
libvlc_instance_t* instance;
libvlc_media_t* media;
libvlc_media_player_t* player;
struct videoContext
{
unsigned char *pixeldata;
unsigned char currentFrame;
int width;
int height;
};
struct videoContext mainContext;
bool gotData = false;
int width;
int height;
static void *lock(void *data, void **p_pixels)
{
videoContext* context = (videoContext*)data;
*p_pixels = context->pixeldata;
return NULL;
}
static void unlock(void *data, void *id, void *const *p_pixels)
{
mainContext.currentFrame++;
//If I check here mainContext.pixeldata is filled with 0xCD
}
static void display(void *data, void *id)
{
}
static unsigned int formatSetup(void **opaque, char *chroma, unsigned *w, unsigned *h, unsigned *pitches, unsigned *lines)
{
chroma = "RV24";
width = *w;
height = *h;
mainContext.pixeldata = (unsigned char*)malloc(width * height * 3);
mainContext.width = width;
mainContext.height = height;
return 1;
}
void getVideoSize(int* w, int* h, int* bpp)
{
*w = width;
*h = height;
*bpp = 3 * 8;
}
videoContext* initVideo(const char* fileName)
{
mainContext.pixeldata = 0;
instance = libvlc_new(0, NULL);
media = libvlc_media_new_location(instance, fileName);
player = libvlc_media_player_new_from_media(media);
libvlc_video_set_callbacks(player, lock, unlock, display, &mainContext);
libvlc_video_set_format_callbacks(player, formatSetup, NULL);
libvlc_media_player_play(player);
return &mainContext;
}
UPDATE:
It seems that nothing is being written to the buffer as anything I set is left there.
UPDATE2:
If I remove the format setup callback and I hardcode libvlc_video_set_format with the "RV24" chroma mode and the resolution it works, so, did I understood wrongly what libvlc_video_set_format_callbacks does?
According to the documentation on the format setup callback the params can be changed to enable transcoding but even if I just leave the format as is whenever I set the format setup callback it doesn't works...
Ok, so, the problem was extrmely stupid. First, the pitches and lines must be set so libvlc to know the allocated sizes. Second, can't just assign chroma with a const char, it seems as the const char has an extra "\0x00" at the end liblvc counts it and then doesn't finds the decoder.
The final callback is this:
static unsigned int formatSetup(void **opaque, char *chroma, unsigned *w, unsigned *h, unsigned *pitches, unsigned *lines)
{
memcpy(chroma, "RV24", sizeof("RV24") - 1);
width = *w;
height = *h;
*pitches = width * 3;
*lines = height;
mainContext.pixeldata = (unsigned char*)malloc(width * height * 4);
mainContext.width = width;
mainContext.height = height;
return 1;
}
I want to play a buffer in libvlc which is filled by a signal/slot from another thread. I've used read_callbacks of libvlc but it can be compiled with mingw and compiling it for msvc is a hard process (see here).(I want to compile my program in msvc2012). so I want to use imem option and I wrote the following code but it crashed and do not show anything.
#include <QMainWindow>
#include <QFile>
#include <vlc/vlc.h>
#include <vlc/libvlc_media_player.h>
#include <vlc/libvlc_media.h>
using namespace std ;
const int len = (820 * 600 * 4) + 31;
int imemGetCallback (void *data, const char *cookie,int64_t *dts, int64_t *pts,unsigned *flags, size_t * bufferSize, void ** buffer);
int imemReleaseCallback (void *data, const char *cookie, size_t bufferSize, void * buffer);
int main(){
char smem_options1[2000];
char venc_options[1000];
sprintf(venc_options,"bframes=6,ref=6");
char str_imem_get[100], str_imem_release[100],str_imem_data[100];
sprintf(str_imem_get, "--imem-get=%ld", imemGetCallback);
sprintf(str_imem_release, "--imem-release=%ld", imemReleaseCallback);
const char * const vlc_args[] = {
"-I","dummy",
"--ignore-config",
"--demux","rawvideo",
"--rawvid-fps","30",
"--rawvid-width","820",
"--rawvid-height","600",
"--rawvid-chroma","RV24",
"--imem-channels=1",
"--imem-data=0",
"--imem-cat=4",
"--imem-fps=30",
"--imem-codec=none",
str_imem_get,
str_imem_release
};
libvlc_instance_t * inst_broadcast =libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);;// libvlc_new(vlc_argc, vlc_argv);
libvlc_media_t * m = libvlc_media_new_location(inst_broadcast, "imem://");
auto _vlcmp = libvlc_media_player_new_from_media(m);
libvlc_media_player_play(_vlcmp);
}
int imemGetCallback (void *data, const char *cookie,int64_t *dts, int64_t *pts,unsigned *flags, size_t * bufferSize, void ** buffer)
{
int64_t uS = 33333; // 30 fps
static int index=0;
*bufferSize = len;
*buffer = buf;
*dts = *pts = 33333;
return 1;
}
int imemReleaseCallback (void *data, const char *cookie, size_t bufferSize, void * buffer)
{
return 0;
}
how can I use imem option to do the job?