Want some guide about how to use nvjpegEncodeYUV() - encoding

I am trying to implement some jpeg encoding cuda code based one a sample code below:
https://docs.nvidia.com/cuda/nvjpeg/index.html#nvjpeg-encode-examples
I post all the code, test result and Makefile and input file.
I am testing with NVIDIA 2080 HW + cuda 11.2
But as you would be able to find from this question, the result is fail. First fail is from nvjpegEncodeYUV() The returned error code is 2. That complains for some invalid parameters. What might be wrong?
#include <iterator>
#include <fstream>
#include <iostream>
#include <vector>
#include <cassert>
#include <unistd.h>
#include "nppdefs.h"
#include "nppi_support_functions.h"
#include "nppi_color_conversion.h"
#include "nvjpeg.h"
#include "cuda_runtime.h"
#define DEFAULT_RAWFILE "./uyvy422.raw"
//file >>> buff_UYVY
int read_raw(const char *file2read, unsigned char *buff_UYVY)
{
if (!file2read) {
std::cout << "file2read empty!!" << std::endl;
return 1;
}
if (!buff_UYVY) {
std::cout << "buff_UYVY empty!!" << std::endl;
return 1;
}
std::string file_uyvy(file2read);
std::ifstream stream_uyvy;
stream_uyvy.open(file_uyvy, std::ios::in | std::ios::binary);
if (!stream_uyvy.is_open())
{
std::cerr << "[ERROR] cannot open the raw file " << file_uyvy
<< std::endl;
std::cerr << std::endl;
assert(0);
}
stream_uyvy.read((char*)buff_UYVY, 1920*1080*2);
stream_uyvy.close();
return 0;
}
int main(int argc, char*argv[])
{
unsigned char *buff_UYVY =
new unsigned char[1920 * 1080 * 2];
//file >>> buff_UYVY
int ret;
if (argv[1]) {
ret = read_raw(argv[1], buff_UYVY);
} else {
ret = read_raw(DEFAULT_RAWFILE, buff_UYVY);
}
if (ret != 0) {
std::cout << "read_raw() failed!!" << std::endl;
return ret;
}
if (!buff_UYVY) {
std::cout << "buff_UYVY empty!!" << std::endl;
return 1;
}
cudaError_t err_cu_api;
Npp8u* gpu_buff_CbYCr422;
err_cu_api = cudaMalloc((void**)&gpu_buff_CbYCr422,
1920*1080*2);
err_cu_api = cudaMemcpy((void*)gpu_buff_CbYCr422,
(const void*)buff_UYVY,
1920*1080*2,
cudaMemcpyHostToDevice);
//////////////////////////////////////////////////////////////////////////////
//https://docs.nvidia.com/cuda/nvjpeg/index.html#nvjpeg-encode-examples
nvjpegStatus_t status;
nvjpegHandle_t nv_handle;
nvjpegEncoderState_t nv_enc_state;
nvjpegEncoderParams_t nv_enc_params;
cudaStream_t stream = 0;
// initialize nvjpeg structures
status = nvjpegCreateSimple(&nv_handle);
std::cout << "nvjpegCreateSimple : " << status << std::endl;
status = nvjpegEncoderStateCreate(nv_handle, &nv_enc_state, stream);
std::cout << "nvjpegEncoderStateCreate : " << status << std::endl;
status = nvjpegEncoderParamsCreate(nv_handle, &nv_enc_params, stream);
std::cout << "nvjpegEncoderParamsCreate : " << status << std::endl;
nvjpegImage_t imgdesc =
{
{
gpu_buff_CbYCr422,
gpu_buff_CbYCr422 + 1920*1080,
gpu_buff_CbYCr422 + 1920*1080*2,
gpu_buff_CbYCr422 + 1920*1080*3
},
{
1920,
1920,
1920,
1920
}
};
// Compress image
status = nvjpegEncodeYUV(nv_handle, nv_enc_state, nv_enc_params,
&imgdesc, NVJPEG_CSS_422, 1920, 1080,
stream);
std::cout << "nvjpegEncodeYUV : " << status << std::endl;
// get compressed stream size
size_t length;
status = nvjpegEncodeRetrieveBitstream(nv_handle, nv_enc_state, NULL,
&length, stream);
std::cout << "nvjpegEncodeRetrieveBitstream : " << status << std::endl;
// get stream itself
cudaStreamSynchronize(stream);
std::vector<char> jpeg(length);
status = nvjpegEncodeRetrieveBitstream(nv_handle, nv_enc_state,
(unsigned char*)jpeg.data(), &length, 0);
std::cout << "nvjpegEncodeRetrieveBitstream : " << status << std::endl;
// write stream to file
cudaStreamSynchronize(stream);
std::ofstream output_file("test.jpg", std::ios::out | std::ios::binary);
output_file.write(jpeg.data(), length);
output_file.close();
//https://docs.nvidia.com/cuda/nvjpeg/index.html#nvjpeg-encode-examples
//////////////////////////////////////////////////////////////////////////////
cudaFree(gpu_buff_CbYCr422);
err_cu_api = err_cu_api;
delete[] buff_UYVY;
return 0;
}
$ ./test
nvjpegCreateSimple : 0
nvjpegEncoderStateCreate : 0
nvjpegEncoderParamsCreate : 0
nvjpegEncodeYUV : 2
nvjpegEncodeRetrieveBitstream : 2
nvjpegEncodeRetrieveBitstream : 2
CC = g++
CFLAGS = -v -Wall -I/usr/local/cuda/include -g
LDFLAGS += -L/usr/local/cuda/lib64
SRCS = main_gpu.cpp
PROG = test
OPENCV = `pkg-config opencv4 --cflags --libs`
LIBS = $(OPENCV) \
-lcudart \
-lnppisu \
-lnpps \
-lnppc \
-lnppial \
-lnppicc \
-lnppidei \
-lnppif \
-lnppig \
-lnppim \
-lnppist \
-lnppitc \
-lnvjpeg
.PHONY: all clean
all: $(PROG)
$(PROG):$(SRCS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(PROG) $(SRCS) $(LIBS)
clean:
rm -f $(OBJS) $(PROG) *.jpg *.bmp
getting input file:
git clone https://github.com/jumogehn/Jumogehn.git
uyvy422.raw is it.

Based on what I see in your code, I'm guessing your input storage format is ordinary YUV422:
U0 Y0 V0 Y1 U2 Y2 V2 Y3 U4 Y4 V4…
That is an interleaved storage format. However the docs for nvjpegEncodeYUV state:
The source argument should be filled with the corresponding YUV planar data.
So you would need to convert your interleaved input into planar storage of a Y plane followed by a U plane followed by a V plane.
As a result, your imgdesc would need to change, because the pitch of U and V planes is half that of the Y plane:
nvjpegImage_t imgdesc =
{
{
gpu_buff_CbYCr422, // pointer to start of Y plane
gpu_buff_CbYCr422 + 1920*1080, // pointer to start of U plane
gpu_buff_CbYCr422 + 1920*1080 + 960*1080, // pointer to start of V plane
NULL
},
{
1920, // pitch of Y plane
960, // pitch of U plane
960, // pitch of V plane
0
}
};
Finally, it seems you need to set the Sampling Factors in the Params:
$ cat t2017.cpp
#include "nvjpeg.h"
#include "cuda_runtime.h"
#include <iostream>
#define DEFAULT_RAWFILE "./uyvy422.raw"
int main(int argc, char*argv[])
{
unsigned char *buff_UYVY =
new unsigned char[1920 * 1080 * 2];
cudaError_t err_cu_api;
unsigned char* gpu_buff_CbYCr422;
err_cu_api = cudaMalloc((void**)&gpu_buff_CbYCr422,
1920*1080*2);
err_cu_api = cudaMemcpy((void*)gpu_buff_CbYCr422,
(const void*)buff_UYVY,
1920*1080*2,
cudaMemcpyHostToDevice);
//////////////////////////////////////////////////////////////////////////////
//https://docs.nvidia.com/cuda/nvjpeg/index.html#nvjpeg-encode-examples
nvjpegStatus_t status;
nvjpegHandle_t nv_handle;
nvjpegEncoderState_t nv_enc_state;
nvjpegEncoderParams_t nv_enc_params;
cudaStream_t stream = 0;
// initialize nvjpeg structures
status = nvjpegCreateSimple(&nv_handle);
std::cout << "nvjpegCreateSimple : " << status << std::endl;
status = nvjpegEncoderStateCreate(nv_handle, &nv_enc_state, stream);
std::cout << "nvjpegEncoderStateCreate : " << status << std::endl;
status = nvjpegEncoderParamsCreate(nv_handle, &nv_enc_params, stream);
std::cout << "nvjpegEncoderParamsCreate : " << status << std::endl;
nvjpegImage_t imgdesc =
{
{
gpu_buff_CbYCr422,
gpu_buff_CbYCr422 + 1920*1080,
gpu_buff_CbYCr422 + 1920*1080 + 960*1080,
NULL
},
{
1920,
960,
960,
0
}
};
status = nvjpegEncoderParamsSetSamplingFactors(nv_enc_params, NVJPEG_CSS_422, stream);
std::cout << "nvjpegEncoderParamsSetSamplingFactors: " << status << std::endl;
// Compress image
status = nvjpegEncodeYUV(nv_handle, nv_enc_state, nv_enc_params,
&imgdesc, NVJPEG_CSS_422, 1920, 1080,
stream);
std::cout << "nvjpegEncodeYUV : " << status << std::endl;
}
$ g++ t2017.cpp -I/usr/local/cuda/include -L/usr/local/cuda/lib64 -lnvjpeg -lcudart -o t2017
$ ./t2017
nvjpegCreateSimple : 0
nvjpegEncoderStateCreate : 0
nvjpegEncoderParamsCreate : 0
nvjpegEncoderParamsSetSamplingFactors: 0
nvjpegEncodeYUV : 0
$
I'm not suggesting this fixes every possible error in your code, merely that it seems to address this question:
First fail is from nvjpegEncodeYUV() The returned error code is 2. That complains for some invalid parameters. What might be wrong?

Related

Memory leak in C++ VScode with mingw-64 ,CRT: _CrtDumpMemoryLeaks() not showing the memory leak

I am on windows 11 using VScode to run a C++ code with ming-w64.
I have installed ming-w64 following all these steps
I am running a code that has a deliberate memory leak to see if there is a report by _CrtDumpMemoryLeaks().
this is my code:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include <iostream>
#ifdef _DEBUG
#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
// Replace _NORMAL_BLOCK with _CLIENT_BLOCK if you want the
// allocations to be of _CLIENT_BLOCK type
#else
#define DBG_NEW new
#endif
using namespace std;
int main()
{
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_DEBUG );
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
int *i2 = new int(2);
cout << "address of i2 :" << i2 << endl;
bool check = _CrtDumpMemoryLeaks();
cout << "MEMORY check :" << check << endl;
cout << "After CrtDumpMemoryLeaks" << endl;
}
This is the TERMINAL:
PS C:\Users\שראל\Desktop\C_proj\projects\helloworld> & 'c:\Users\שראל\.vscode\extensions\ms-vscode.cpptools-1.9.7\debugAdapters\bin\WindowsDebugLauncher.exe' '--stdin=Microsoft-MIEngine-In-o0zd5lqu.up2' '--stdout=Microsoft-MIEngine-Out-gva0ndx0.ycm' '--stderr=Microsoft-MIEngine-Error-eec2m2xg.4x5' '--pid=Microsoft-MIEngine-Pid-fakhxofs.oyp' '--dbgExe=C:\msys64\mingw64\bin\gdb.exe' '--interpreter=mi'
address of i2 :0x190a9ff1a90
MEMORY check :0
After CrtDumpMemoryLeaks
And the OUTPUT is empty.
I don't understand what I am doing wrong here.

How can i send and recv multiple files size in one socket c++?

i'm trying to develop a client/server application to share files..
1- Client send file size
2- Client send file data (name + content)
3- Server recv file size
4- Server recv file data (name + content)
I have my code that is working good for one file, and i'm asking how to edit it so i can send and receive size of multiple files ?
Can anyone help Plz !!!
Client code :
cout << "[Client] Sending files name to the Server... " << endl ;
int i=0;
while(i<files_vector.size()){
/************ Read & Send filename *************/
string filename = files_vector[i].getFullNameFile();
string test = filename+"&&";
size_t nameLen = strlen(test.c_str());
if(filename == "." || filename == "..")
continue;
string path_file = cf.pathSrcFiles+filename;
std::ifstream infile(path_file, std::ifstream::binary);
int32_t sizef = files_vector[i].getTaille();
/*** Send file size to server ***/
char fsize[256];
sprintf(fsize, "%d", nameLen+sizef);
if(send(sock, fsize, sizeof(fsize),0) < 0){
perror("Error sending file size\n");
exit(1);
}
/**** Send file data ****/
char content_file[sizef];
bzero(content_file, sizef);
infile.read(content_file,sizef);
string concat = test+string(content_file);
char file[sizef];
strcpy(file, concat.c_str());
cout << "content : " << file << endl;
cout << "size : " << nameLen+sizef << endl;
if(send(sock, file, nameLen+sizef, 0) < 0)
{
cout << stderr << "ERROR: Failed to send file" << filename << "
(error no = " << errno << ")" << endl;
break;
}
bzero(content_file, sizef);
infile.close();
cout << "Ok File " << filename << " from Client was Sent!\n" << endl;
i++;
}
Server code :
char csize[256];
int rc;
int32_t fsize;
/** Receive file size **/
if(rc = recv(sock, csize, 256, 0)) < 0){
cout << "Error receiving file size" << endl;
exit(1);
}
csize[rc] = '\0';
fsize = atoi(csize);
int n = 0;
int bytes_read = 0;
char* file;
file = new char[fsize];
memset(file, 0, fsize);
/** Receive file data **/
while((n = recv(sock, file+bytes_read, fsize-bytes_read, 0) > 0) &&
(bytes_read < fsize)){
cout << "content : " << file << endl;
bytes_read += n;
memset(file, 0, fsize);
}
delete[] file;

How fix strange syntax problem when using execute function?

I met an error when trying to use a function called execute to use one database. The information shows me that's about syntax, but I don't think so.
The following is my critical code and important information about the error.
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'u' at line 1
#include <stdlib.h>
#include <iostream>
/*
Include directly the different
headers from cppconn/ and mysql_driver.h + mysql_util.h
(and mysql_connection.h). This will reduce your build time!
*/
#include<string>
#include "mysql_connection.h"
#include <mysql_driver.h>
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
using namespace std;
using namespace sql;
int main()
{
try {
sql::mysql::MySQL_Driver driver;
cout<<" driver "<<endl;
sql::Connection *con = NULL;
cout<<" con"<<endl;
sql::Statement *stmt;
cout<<" stmt"<<endl;
sql::ResultSet *res;
cout<<" res"<<endl;
/* Create a connection */
//driver = sql::mysql::MySQL_Driver::MySQL_Driver();
SQLString ip_port("localhost:3306");
cout<<"some debug string"<<endl;
SQLString user("debian-sys-maint");
SQLString password("fTlykRye1LwttC8f");
con = driver.connect(ip_port, user, password);
assert(con!=NULL);
cout<<" root"<<endl;
/* Connect to the MySQL test database */
SQLString schema("account");
//con->setSchema(schema);
cout<<" table"<<endl;
stmt = con->createStatement();
cout<<" table*2"<<endl;
assert(stmt!=NULL);
SQLString db("use account");
stmt->execute(db);
res = stmt->executeQuery("SELECT * from user");
while (res->next()) {
cout << "\t... MySQL replies: ";
/* Access column data by alias or column name */
cout << res->getString("name") << endl;
cout << "\t... MySQL says it again: ";
/* Access column data by numeric offset, 1 is the first column */
cout << res->getString("password") << endl;
}
delete res;
delete stmt;
delete con;
} catch (sql::SQLException &e) {
cout << "# ERR: SQLException in " << __FILE__;
cout << "(" << __FUNCTION__ << ") on line "<<endl;
cout << "# ERR: " << e.what();
cout << " (MySQL error code: " << e.getErrorCode();
cout << ", SQLState: " << e.getSQLState() << " )" << endl;
cout<<"\n";
}
cout << endl;
return EXIT_SUCCESS;
}
I was confused that why the information was not about the sentence "use account". Instead, it was about "u". Thanks very much.
USER is a reserved word/keyword in MySQL.
You should delimit your field names with backticks to avoid problems:
SELECT * FROM `user`

d aGetting error while connecting to Postgres via dev c++

I am trying to get connected to Postgres database via Dev-c++ (Windows application and not console) for executing queries, but I am continuously getting errors.
I went through the following link:
http://www.tutorialspoint.com/postgresql/postgresql_c_cpp.htm
and added the below code to that of mine:
#include <iostream>
#include <pqxx/pqxx>
using namespace std;
using namespace pqxx;
int main(int argc, char* argv[])
{
try{
connection C("dbname=testdb user=postgres password=cohondob \
hostaddr=127.0.0.1 port=5432");
if (C.is_open()) {
cout << "Opened database successfully: " << C.dbname() << endl;
} else {
cout << "Can't open database" << endl;
return 1;
}
C.disconnect ();
}catch (const std::exception &e){
cerr << e.what() << std::endl;
return 1;
}
}
But got error stating:
'No such file or directory
#include
Compilation terminated'
Please, Can anyone help me get through this?
is there any other possible way to get connected?

replace the text with pre and post string

I have file in which there are certian lines which have common string:
_report_file <<
SO the text around this above can be any thingbut it ends with semiclon(;)
for eg see the line below:
CACUP_updater::_report_file << "The job has terminated." << endl;
another example of the line can be:
_report_file << "The job is reading." << endl;
i need to append abc; as pre string and xyz; as post string to that line so that the line looks like
abc;CACUP_updater::_report_file << "The job has terminated." << endl;xyz;
basically i want to search for "_report_file <<",select the complete line and pre and post append some text.
how can i do this in sed or perl or awk.
A perl way:
perl -anE 'chomp;s/^(.*?::_report_file <<.*;)$/abc;$1xyz;/;say;' foo.txt > foo2.txt
or
perl -ane 'chomp;s/^(.*?::_report_file <<.*;)$/abc;${1}xyz;/;print "$_\n";' foo.txt > foo2.txt
$ perl -i.bak -n -e 'print "abc;${_}xyz;"' your_file_here
That'll give you a backup copy of the file too.
awk '/_report_file <</{$0="abc;" $0 "xyz;"}{print}'
perl -pi.bak -e 's{.*_report_file <<.*}{abc;$&xyz;}' file_name_here
Edit in response to your updated question. I think you're doing it wrong :)
I suggest you do it this way instead:
#!/usr/bin/perl
use strict;
use warnings;
while(<>)
{
s/([\w]+::)?_report_file\s*<<\s*(.*);/CACUP_REPORT($2);/go;
print
}
That way, you can, in C++, define a macro like
#define CACUP_REPORT(message) do { \
/* abc; */ \
::CACUP_updater::_report_file << message; \
/* xyz; */ } while (false)
But Why?
You can read all about safe macros elsewhere 1.
You get way more flexibility. You can later change all instances at one point.
You can delegate to a a function
You could declare a temporary stringstream and write the resulting text to a whole other medium (network? fwrite? memory buffer? two streams?).
You could make the logging conditional depending on a global falg without having to duplicate the check for it throughour your code.
Well you get it: it pretty much the DRY principle.
Sample input:
#include <iostream>
using namespace std;
namespace CACUP_updater
{
std::ostream& _report_file = std::cout;
void start_reading()
{
_report_file << "The job is reading." << endl;
}
}
int main()
{
CACUP_updater::_report_file << "The job is starting." << endl;
CACUP_updater::start_reading();
CACUP_updater::_report_file << "The job has terminated." << endl;
}
Sample output:
The result of, e.g. perl -i.bck test.cpp is 2:
#include <iostream>
using namespace std;
namespace CACUP_updater
{
std::ostream& _report_file = std::cout;
void start_reading()
{
CACUP_REPORT("The job is reading." << endl);
}
}
int main()
{
CACUP_REPORT("The job is starting." << endl);
CACUP_updater::start_reading();
CACUP_REPORT("The job has terminated." << endl);
}
Some ideas for implementations of the macro:
This shows how you can
use a temporary stream to stringify
print to more than one output stream, conditionally
handle exceptions properly inline
add a datetime stamp (only for writing to the log file, not stderr)
of course, there is more than enough room to accomodate any abc; or xyz; you had in mind :)
.
#include <iostream>
#include <sstream>
#include <fstream>
using namespace std;
static bool _verbose = false;
#define CACUP_REPORT(message) do { \
std::stringstream ss; \
ss << message; \
::CACUP_updater::log_helper(ss.str()); \
} while (false)
namespace CACUP_updater
{
std::string getdatetime() { return "YYYY/MM/DD - HH:MM:SS.mmm"; } // demo only
void log_helper(const std::string& msg)
{
try
{
std::ofstream ofs("/tmp/myprogram.log", std::ios_base::app);
ofs << getdatetime() << "\t" << msg;
ofs.flush();
ofs.close();
// log errors always to stderr,
// and all other messages if verbose is set
if (_verbose || std::string::npos != msg.find("ERROR"))
std::cerr << msg << std::endl;
} catch(std::exception& e)
{
std::cerr << "Unhandled error writing to log: '" << e.what() << std::endl;
}
}
void start_reading()
{
CACUP_REPORT("The job is reading." << endl);
}
}
int main()
{
CACUP_REPORT("The job is starting." << endl);
CACUP_updater::start_reading();
CACUP_REPORT("The job has terminated." << endl);
}
The output to the file is:
YYYY/MM/DD - HH:MM:SS.mmm The job is starting.
YYYY/MM/DD - HH:MM:SS.mmm The job is reading.
YYYY/MM/DD - HH:MM:SS.mmm The job has terminated.
The output to the stderr depends on the verbose flag
1 just imagine what would happen if if (b) _report_file << "ok!" << std::endl; ?
2 note that a backup file is created: test.cpp.bck