I found in cocos2d-x library, there is a file named ccFPSImage.c which is a hex format array of the FPS images. Cocos2D-x use it for displaying FPS.
I just want to know how I can generate that file.
The file content is like this:
unsigned char cc_fps_images_png[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x03, 0xe7, 0x00, 0x00, 0x00, 0x36,
0x08, 0x06, 0x00, 0x00, 0x00, 0xa5, 0x74, 0xe8, 0xab, 0x00, 0x00, 0x0a,
0x41, 0x69, 0x43, 0x43, 0x50, 0x49, 0x43, 0x43, 0x20, 0x50, 0x72, 0x6f,
0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x48, 0x0d, 0x9d, 0x96, 0x77, 0x54,
0x53, 0xd9, 0x16, 0x87, 0xcf, 0xbd, 0x37, 0xbd, 0xd0, 0x12, 0x22, 0x20,
.... (There are a lot of hex values here, I just omit them here)
}
I have use the ImageMagick tool to generate the .h file, but when it loaded, it just report:
cocos2d: the file is not a dds file!
cocos3d: the file is not a ktx file!
Image WARNING: unsupport true color tga data pixel format. FILE:
Fails: init fps_images
cocos2d: the file is not a dds file!
cocos3d: the file is not a ktx file!
Image WARNING: unsupport true color tga data pixel format. FILE:
Fails: init fps_images
cocos2d: the file is not a dds file!
cocos3d: the file is not a ktx file!
Image WARNING: unsupport true color tga data pixel format. FILE:
Fails: init fps_images
I use the following command to generate the .h file:
convert fps.png h:->fps.h
Does anyone know how to generate a valid ccFPSImage.c file?
Thanks.
Until now, ImageMagick's "convert file h:file.h" would create a header file containing either a GIF or a PPM image.
ImageMagick version 6.9.1-10 will support a new "-define h:format=PNG" option that will create the file you expected.
convert fps.png -define h:format=PNG -define png:exclude-chunks=all h:fps.h
(The "-define png:exclude-chunks=all" will cause convert to omit unwanted ancillary PNG chunks containing create/modify date, etc.)
JPEG output will also be supported, via "-define h:format=JPG".
Related
I'm using a netgear WNDR4300 to run GraphicsMaigick to resize JPEG images.
This is the cpuinfo,
cat /proc/cpuinfo
system type : Atheros AR9344 rev 2
machine : NETGEAR WNDR4300
processor : 0
cpu model : MIPS 74Kc V4.12
BogoMIPS : 278.93
wait instruction : yes
microsecond timers : yes
tlb_entries : 32
extra interrupt vector : yes
hardware watchpoint : yes, count: 4, address/irw mask: [0x0ffc, 0x0ffc, 0x0ffb, 0x0ffb]
isa : mips1 mips2 mips32r1 mips32r2
ASEs implemented : mips16 dsp dsp2
shadow register sets : 1
kscratch registers : 0
package : 0
core : 0
VCED exceptions : not available
VCEI exceptions : not available
It's very slow, and took over 4 minuntes for every photo.
root#OpenWrt:/mnt/sda1/media/# ll
drwxrwxrwx 2 root root 131072 Jun 10 14:07 ./
drwxrwxrwx 7 root root 131072 Jun 8 10:18 ../
-rwxrwxrwx 1 root root 4130026 Feb 10 2018 IMG_20180210_115807.jpg*
root#OpenWrt:/mnt/sda1/media/kidds# time gm mogrify -output-directory > /mnt/sda1/web -resize 64x64 -quality 75 IMG_20170628_100052.jpg
real 4m 19.72s
user 3m 21.86s
sys 0m 9.29s
UPDATE:
root#OpenWrt:~# gm identify -version
GraphicsMagick 1.3.31 2018-11-17 Q8 http://www.GraphicsMagick.org/
Copyright (C) 2002-2018 GraphicsMagick Group.
Additional copyrights and licenses apply to this software.
See http://www.GraphicsMagick.org/www/Copyright.html for details.
Feature Support:
Native Thread Safe yes
Large Files (> 32 bit) yes
Large Memory (> 32 bit) no
BZIP no
DPS no
FlashPix no
FreeType yes
Ghostscript (Library) no
JBIG no
JPEG-2000 no
JPEG yes
Little CMS no
Loadable Modules yes
OpenMP no
PNG yes
TIFF yes
TRIO no
UMEM no
WebP no
WMF no
X11 no
XML no
ZLIB yes
Host type: mips-openwrt-linux-gnu
Configured using the command:
./configure '--target=mips-openwrt-linux' '--host=mips-openwrt-linux' '--build=x86_64-pc-linux-gnu' '--program-prefix=' '--program-suffix=' '--prefix=/usr' '--exec-prefix=/usr' '--bindir=/usr/bin' '--sbindir=/usr/sbin' '--libexecdir=/usr/lib' '--sysconfdir=/etc' '--datadir=/usr/share' '--localstatedir=/var' '--mandir=/usr/man' '--infodir=/usr/info' '--disable-nls' '--enable-shared' '--disable-static' '--enable-dependency-tracking' '--with-modules' '--with-threads' '--without-magick-plus-plus' '--without-perl' '--without-bzlib' '--without-dps' '--without-fpx' '--without-jbig' '--without-webp' '--with-jpeg' '--without-jp2' '--without-lcms2' '--without-lzma' '--with-png' '--with-tiff' '--without-trio' '--with-ttf' '--without-umem' '--without-wmf' '--without-xml' '--with-zlib' '--without-zstd' '--without-x' 'build_alias=x86_64-pc-linux-gnu' 'host_alias=mips-openwrt-linux' 'target_alias=mips-openwrt-linux' 'CC=mips-openwrt-linux-musl-gcc' 'CFLAGS=-Os -pipe -mno-branch-likely -mips32r2 -mtune=24kc -fno-caller-save
Final Build Parameters:
CC = mips-openwrt-linux-musl-gcc
CFLAGS = -Os -pipe -mno-branch-likely -mips32r2 -mtune=24kc -fno-caller-saves -fno-plt -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -msoft-float -mips16 -minterlink-mips16 -iremap/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/build_dir/target-mips_24kc_musl/GraphicsMagick-1.3.31:GraphicsMagick-1.3.31 -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro -flto -Wall
CPPFLAGS = -I/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/target-mips_24kc_musl/usr/include -I/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/target-mips_24kc_musl/include -I/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/usr/include -I/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/include/fortify -I/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/include -I/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/target-mips_24kc_musl/usr/include/freetype2
CXX = mips-openwrt-linux-musl-g++
CXXFLAGS = -Os -pipe -mno-branch-likely -mips32r2 -mtune=24kc -fno-caller-saves -fno-plt -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -msoft-float -mips16 -minterlink-mips16 -iremap/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/build_dir/target-mips_24kc_musl/GraphicsMagick-1.3.31:GraphicsMagick-1.3.31 -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro -flto
LDFLAGS = -L/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/target-mips_24kc_musl/usr/lib -L/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/target-mips_24kc_musl/lib -L/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/usr/lib -L/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/lib -znow -zrelro -L/opt/buildbot/slaves/lede-slave-tah/mips_24kc/build/sdk/staging_dir/target-mips_24kc_musl/usr/lib
LIBS = -lfreetype -lz -lltdl -lm -lpthread
UPDATE2: sample mode
root#OpenWrt:/mnt/sda1/media/kidds# time gm mogrify -output-directory /mnt/sda1/web -sample 64x64 -quality 75 IMG_20170628_100052.jpg
real 0m 20.76s
user 0m 8.70s
sys 0m 3.29s
Is there any way to improve the performance? I just want resize some photoes, if there is some library provided by MIPS, I can write a tool to call it using C language.
I grabbed the file example.c from the v9c source on the IJG website and quickly hacked it about as below to only write every 8th row and every 8th column from your 4640x3480 input file. It creates the following 580x435 image which GraphicsMagick can then presumably manage to resize down to 64x64 in reasonable time since the file is 64x smaller.
You would use:
gm convert result.ppm -resize 64x64 thumb.jpg
It only uses 1.1MB of RAM because it only reads 1 line at a time - I tested using:
/usr/bin/time -l ./example photo.jpg
You could experiment with the decimation factor, I used 8, but you could try 4, or 10 and see the tradeoff between time and quality. Just change the 8 on the second-to-last line of the file.
The code looks like this - I have added "HACK" in the comments so you can see where I was busy making ugly dirty code:
#include <stdio.h>
#include <stdlib.h>
#include "jpeglib.h"
#include <setjmp.h>
struct my_error_mgr {
struct jpeg_error_mgr pub; /* "public" fields */
jmp_buf setjmp_buffer; /* for return to caller */
};
typedef struct my_error_mgr * my_error_ptr;
METHODDEF(void)
my_error_exit (j_common_ptr cinfo)
{
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
my_error_ptr myerr = (my_error_ptr) cinfo->err;
/* Always display the message. */
/* We could postpone this until after returning, if we chose. */
(*cinfo->err->output_message) (cinfo);
/* Return control to the setjmp point */
longjmp(myerr->setjmp_buffer, 1);
}
GLOBAL(int)
read_JPEG_file (char * filename,int factor)
{
/* This struct contains the JPEG decompression parameters and pointers to
* working space (which is allocated as needed by the JPEG library).
*/
struct jpeg_decompress_struct cinfo;
/* We use our private extension JPEG error handler.
* Note that this struct must live as long as the main JPEG parameter
* struct, to avoid dangling-pointer problems.
*/
struct my_error_mgr jerr;
/* More stuff */
FILE * infile; /* source file */
FILE * outfile; /* result file */ // HACK
JSAMPARRAY buffer; /* Output row buffer */
int row_stride; /* physical row width in output buffer */
/* In this example we want to open the input file before doing anything else,
* so that the setjmp() error recovery below can assume the file is open.
* VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
* requires it in order to read binary files.
*/
if ((infile = fopen(filename, "rb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
return 0;
}
/* Step 1: allocate and initialize JPEG decompression object */
/* We set up the normal JPEG error routines, then override error_exit. */
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
/* Establish the setjmp return context for my_error_exit to use. */
if (setjmp(jerr.setjmp_buffer)) {
/* If we get here, the JPEG code has signaled an error.
* We need to clean up the JPEG object, close the input file, and return.
*/
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return 0;
}
/* Now we can initialize the JPEG decompression object. */
jpeg_create_decompress(&cinfo);
/* Step 2: specify data source (eg, a file) */
jpeg_stdio_src(&cinfo, infile);
/* Step 3: read file parameters with jpeg_read_header() */
(void) jpeg_read_header(&cinfo, TRUE);
/* We can ignore the return value from jpeg_read_header since
* (a) suspension is not possible with the stdio data source, and
* (b) we passed TRUE to reject a tables-only JPEG file as an error.
* See libjpeg.txt for more info.
*/
/* Step 4: set parameters for decompression */
/* In this example, we don't need to change any of the defaults set by
* jpeg_read_header(), so we do nothing here.
*/
/* Step 5: Start decompressor */
(void) jpeg_start_decompress(&cinfo);
/* We can ignore the return value since suspension is not possible
* with the stdio data source.
*/
/* We may need to do some setup of our own at this point before reading
* the data. After jpeg_start_decompress() we have the correct scaled
* output image dimensions available, as well as the output colormap
* if we asked for color quantization.
* In this example, we need to make an output work buffer of the right size.
*/
/* JSAMPLEs per row in output buffer */
row_stride = cinfo.output_width * cinfo.output_components;
/* Make a one-row-high sample array that will go away when done with image */
buffer = (*cinfo.mem->alloc_sarray)
((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
/* Step 6: while (scan lines remain to be read) */
/* jpeg_read_scanlines(...); */
// Write a simple PPM file called "result.ppm" that can be thumbnailed with GraphicsMagick
// gm convert result.ppm -resize 64x64 thumbnail.jpg
if ((outfile = fopen("result.ppm", "wb")) == NULL) { // HACK
fprintf(stderr, "can't open result.ppm\n"); // HACK
return 0; // HACK
}
int outwidth = cinfo.output_width/factor; // HACK
int outheight = cinfo.output_height/factor; // HACK
fprintf(outfile,"P6\n%d %d\n255\n",outwidth,outheight); // HACK
unsigned char * outbuf; // HACK
outbuf = (unsigned char*)malloc(outwidth*3); // HACK
int line=0; // HACK
while (cinfo.output_scanline < cinfo.output_height) {
/* jpeg_read_scanlines expects an array of pointers to scanlines.
* Here the array is only one element long, but you could ask for
* more than one scanline at a time if that's more convenient.
*/
(void) jpeg_read_scanlines(&cinfo, buffer, 1);
// Do every Nth row // HACK
if(line%factor==0){ // HACK
int pixel,op;
op=0;
for(pixel=0;pixel<row_stride/3;pixel+=factor){
outbuf[op++] = buffer[0][(pixel*3) +0];
outbuf[op++] = buffer[0][(pixel*3) +1];
outbuf[op++] = buffer[0][(pixel*3) +2];
}
fwrite(outbuf,1,op,outfile); // HACK
} // HACK
line++; // HACK
}
/* Step 7: Finish decompression */
(void) jpeg_finish_decompress(&cinfo);
/* Step 8: Release JPEG decompression object */
/* This is an important step since it will release a good deal of memory. */
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return 1;
}
int main(int argc, char*argv[]){
// Read "test.jpg" and only output every 8th row and every 8th column for a 64x size reduction
read_JPEG_file ("test.jpg",8); // HACK
}
I compiled it with:
clang -std=c11 $(pkg-config --cflags --libs libjpeg) example.c -o example
I'm trying to write a NAL unit with a SEI user data message. My code looks like:
typedef struct {
unsigned char type_code;
unsigned char countryCode;
unsigned char countryCodeExtension[2];
unsigned char user_identifier[4];
unsigned char payloadBytes[20];
unsigned char marker_bits;
} userdata_reg_t35;
unsigned char begin[5] = {0x00, 0x00, 0x00, 0x01, 0x06};
unsigned char end[3] = {0x00, sizeof(userdata_reg_t35), 0x80};
userdata_reg_t35 m_userSEIData;
m_userSEIData.countryCode = 0xB5;
m_userSEIData.countryCodeExtension[0] = 0x31;
m_userSEIData.countryCodeExtension[1] = 0x00;
m_userSEIData.user_identifier[0] = 0x34;
m_userSEIData.user_identifier[1] = 0x39;
m_userSEIData.user_identifier[2] = 0x41;
m_userSEIData.user_identifier[3] = 0x47;
m_userSEIData.type_code = 0x03;
m_userSEIData.marker_bits = 0xFF;
sprintf((char*)m_userSEIData.payloadBytes, "%s", "My Payload");
memcpy(target, begin, 5);
memcpy(target + 5, &m_userSEIData, sizeof(userdata_reg_t35));
memcpy(target + 5 + sizeof(userdata_reg_t35), end, 3);
When I playback the file in mplayer or vlc, I receive errors:
[h264 # 0x7f5860c20720] SEI type 3 truncated at 216
What am I doing wrong?
** EDIT **
I have modified the code after reading http://git.videolan.org/?p=x264.git;a=blob;f=encoder/set.c#l563
static const uint8_t uuid[16] = {0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7,
0x96, 0x2c, 0xd8, 0x20, 0xd9, 0x23, 0xee, 0xef};
unsigned char begin[7] = {0x00, 0x00, 0x00, 0x01, 0x06, 0x05, 16 + 20};
char szPayload[20];
memset(szPayload, 0, 20);
sprintf(szPayload, "%s", "My payload");
memcpy(target, begin, 7);
memcpy(target + 7, uuid, 16);
memcpy(target + 7 + 16, szPayload, 20);
but I'm still getting the libav error: https://ffmpeg.org/doxygen/2.6/h264__sei_8c_source.html, line #306. What am I still doing wrong?
This does not look good and it does not map well on the H.264 Annex D spec.
You are adding SEI NAL type, then you are expected to add payloadType, payloadSize values - you don't have them. Then you stated you want unregistered SEI message (type 5) and your content more looks like payload type 4 (apparently you are adding captions). So you need to include that and exclude type_code, then it would look about right.
That is, your unneeded type_code 3 goes in place of expected value of 5/4 and then there is no length. VLC stumbles on exactly this...
See H.264 D.1 SEI payload syntax for details.
UPDATE. Your updated code is incorrect [also] for another reason. You are doing Annex B byte stream with start codes and in the same time you are including 20 zero bytes of payload, which under normal conditions should be updated with emulation prevention bytes.
To compare what you get with what x264 produces, simply open x264 output using binary editor and check the SEI NALs, then compare to yours.
I am reading data from server in h264 format, it write successfully in a .h264 file when we include UINT8 u8NAL[4] = {0x00, 0x00, 0x00, 0x01};.
but when we comment //UINT8 u8NAL[4] = {0x00, 0x00, 0x00, 0x01}; .h264 file store data but we can not see data on Vlc or Qt.
UINT8 u8NAL[4] = {0x00, 0x00, 0x00, 0x01};
char name1[100], name2[100];
_snprintf(name1, 99, "D:\\sizeH264_%p.txt", threadArgs->clientHandle);
_snprintf(name2, 99, "D:\\dataH264_%p.h264", threadArgs->clientHandle);
fp = fopen(name1, "w");
fpFrames = fopen(name2, "wb");
fwrite(u8NAL, 4, 1, fpFrames);
fwrite(threadArgs->tmpStreamParams->spsData, threadArgs->tmpStreamParams->spsDataSize, 1, fpFrames);
0 0 0 1 its a header part of a h264 frame, so in short player can know where I have to start and where to stop, that's way we have to give this hex data to every starting point of frame.
And ya its only require when you store data, otherwise you can give direct frame to player.
In my application (being developed on Windows 8 using MySQL Connector/C++) I am creating prepared statements and deleting them only at the end of the application. But while application is running, I execute queries and delete only result sets.
However, I observed lot of memory remains still allocated and I felt its more than expected. I examine with Visual Leak Detector and to my surprise I found leaks were shown in result set pointer despite I was deleting them appropriately.
So I written demo program that does exactly this. That is create prepared statement, create query, fetch result, delete result (but don't delete the prepared statement at end so that we can see the leaks) and quit.
Here is the demo code MySQL.cpp:
#include "stdafx.h"
#include <conio.h>
#define CPPCONN_LIB_BUILD // We must define this as we are linking mysql connector in static library. It directs build_config.h to not to put __declspec(dllimport) before function declarations.
#include <driver/mysql_connection.h>
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
#include <vld.h> // Visual memory leak detector
int _tmain(int argc, _TCHAR* argv[])
{
sql::Connection *pConnection = NULL;
sql::ResultSet *pResultSet = NULL;
sql::PreparedStatement *pPreparedStatement = NULL;
sql::Driver *driver = NULL;
/* Create a connection */
driver = get_driver_instance();
pConnection = driver->connect("tcp://127.0.0.1:3306", "username", "password");
pConnection->setSchema("MYDB");
pConnection->setAutoCommit(0);
sql::ResultSet* pResultSet;
pPreparedStatement = pConnection->prepareStatement ("select * from mytable where mycolumn > ?"); // mytable has mycolumn that contains 1000 numbers starting from 1
pPreparedStatement->setInt(1, 1);
pResultSet= pPreparedStatement->executeQuery();
int count = pResultSet->rowsCount();
printf("\nTotal rows found %d", count);
delete pResultSet;
// delete pPreparedStatement; // Let's not delete prepared statement to see demo of memory leak in pResultSet
delete pConnection;
printf ("\nDone! Quitting...");
return 0;
}
And here is report:
Visual Leak Detector Version 2.4RC2 installed.
Aggregating duplicate leaks.
Suppressing data dumps.
Outputting the report to E:\MySQL\memory_leak_report.txt
WARNING: Visual Leak Detector detected memory leaks!
---------- Block 65 at 0x0000000068D87EB0: 8 bytes ----------
Leak Hash: 0x38615834, Count: 1, Total 8 bytes
Call Stack (TID 4628):
0x00000000C3EC5630 (File and line number not available): ntdll.dll!RtlAllocateHeap
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\new.cpp (59): MySQLTrials.exe!operator new + 0xA bytes
0x00000000DF30AEE4 (File and line number not available): MySQLTrials.exe!sql::mysql::util::Singleton<sql::mysql::NativeAPI::LibmysqlStaticProxy>::theInstance + 0x44 bytes
0x00000000DF306DB1 (File and line number not available): MySQLTrials.exe!sql::mysql::NativeAPI::getCApiHandle + 0x41 bytes
0x00000000DF2AA5AC (File and line number not available): MySQLTrials.exe!sql::mysql::NativeAPI::MySQL_NativeDriverWrapper::MySQL_NativeDriverWrapper + 0x5C bytes
0x00000000DF2AA51D (File and line number not available): MySQLTrials.exe!sql::mysql::NativeAPI::createNativeDriverWrapper + 0x4D bytes
0x00000000DF28401B (File and line number not available): MySQLTrials.exe!sql::mysql::MySQL_Driver::MySQL_Driver + 0x8B bytes
0x00000000DF28456F (File and line number not available): MySQLTrials.exe!sql::mysql::get_driver_instance_by_name + 0x18F bytes
0x00000000DF284681 (File and line number not available): MySQLTrials.exe!sql::mysql::get_driver_instance + 0x21 bytes
0x00000000DF283E1A (File and line number not available): MySQLTrials.exe!get_driver_instance + 0x1A bytes
e:\mysql\mysql.cpp (22): MySQLTrials.exe!wmain + 0x5 bytes
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c (240): MySQLTrials.exe!__tmainCRTStartup + 0x19 bytes
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c (164): MySQLTrials.exe!wmainCRTStartup
0x00000000C1CF167E (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0x1A bytes
0x00000000C3EDC3F1 (File and line number not available): ntdll.dll!RtlUserThreadStart + 0x21 bytes
---------- Block 413 at 0x0000000068D90FF0: 40 bytes ----------
Leak Hash: 0x7614B12C, Count: 1, Total 40 bytes
Call Stack (TID 4628):
0x00000000C3EC5630 (File and line number not available): ntdll.dll!RtlAllocateHeap
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\new.cpp (59): MySQLTrials.exe!operator new + 0xA bytes
0x00000000DF30C576 (File and line number not available): MySQLTrials.exe!sql::mysql::NativeAPI::MySQL_NativeConnectionWrapper::stmt_init + 0x86 bytes
0x00000000DF28E730 (File and line number not available): MySQLTrials.exe!sql::mysql::MySQL_Connection::prepareStatement + 0xC0 bytes
e:\mysql\mysql.cpp (30): MySQLTrials.exe!wmain + 0x30 bytes
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c (240): MySQLTrials.exe!__tmainCRTStartup + 0x19 bytes
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c (164): MySQLTrials.exe!wmainCRTStartup
0x00000000C1CF167E (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0x1A bytes
0x00000000C3EDC3F1 (File and line number not available): ntdll.dll!RtlUserThreadStart + 0x21 bytes
---------- Block 241 at 0x0000000068D93910: 16 bytes ----------
Leak Hash: 0x447A29BE, Count: 1, Total 16 bytes
Call Stack (TID 4628):
0x00000000C3EC5630 (File and line number not available): ntdll.dll!RtlAllocateHeap
c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory0 (592): MySQLTrials.exe!std::allocator<std::_Container_proxy>::allocate
0x00000000DF28B052 (File and line number not available): MySQLTrials.exe!std::_Wrap_alloc<std::allocator<std::_Container_proxy> >::allocate + 0x32 bytes
0x00000000DF303CA7 (File and line number not available): MySQLTrials.exe!std::_Deque_alloc<0,std::_Deque_base_types<sql::mysql::MySQL_DebugEnterEvent const * __ptr64,std::allocator<sql::mysql::MySQL_DebugEnterEvent const * __ptr64> > >::_Alloc_proxy + 0x37 bytes
0x00000000DF303991 (File and line number not available): MySQLTrials.exe!std::_Deque_alloc<0,std::_Deque_base_types<sql::mysql::MySQL_DebugEnterEvent const * __ptr64,std::allocator<sql::mysql::MySQL_DebugEnterEvent const * __ptr64> > >::_Deque_alloc<0,std::_Deque_base_types<sql::mysql::MySQL_DebugEnterEvent const * __ptr64,std + 0x41 bytes
0x00000000DF303A95 (File and line number not available): MySQLTrials.exe!std::deque<sql::mysql::MySQL_DebugEnterEvent const * __ptr64,std::allocator<sql::mysql::MySQL_DebugEnterEvent const * __ptr64> >::deque<sql::mysql::MySQL_DebugEnterEvent const * __ptr64,std::allocator<sql::mysql::MySQL_DebugEnterEvent const * __ptr64> > + 0x35 bytes
0x00000000DF303ACB (File and line number not available): MySQLTrials.exe!std::stack<sql::mysql::MySQL_DebugEnterEvent const * __ptr64,std::deque<sql::mysql::MySQL_DebugEnterEvent const * __ptr64,std::allocator<sql::mysql::MySQL_DebugEnterEvent const * __ptr64> > >::stack<sql::mysql::MySQL_DebugEnterEvent const * __ptr64,std::d + 0x2B bytes
0x00000000DF302AFE (File and line number not available): MySQLTrials.exe!sql::mysql::MySQL_DebugLogger::MySQL_DebugLogger + 0x3E bytes
0x00000000DF28CD77 (File and line number not available): MySQLTrials.exe!sql::mysql::MySQL_Connection::MySQL_Connection + 0x227 bytes
0x00000000DF284184 (File and line number not available): MySQLTrials.exe!sql::mysql::MySQL_Driver::connect + 0xA4 bytes
e:\mysql\mysql.cpp (23): MySQLTrials.exe!wmain + 0x5B bytes
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c (240): MySQLTrials.exe!__tmainCRTStartup + 0x19 bytes
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c (164): MySQLTrials.exe!wmainCRTStartup
0x00000000C1CF167E (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0x1A bytes
0x00000000C3EDC3F1 (File and line number not available): ntdll.dll!RtlUserThreadStart + 0x21 bytes
---------- Block 483 at 0x0000000068D93960: 11 bytes ----------
Leak Hash: 0x1D599652, Count: 1, Total 11 bytes
Call Stack (TID 4628):
0x00000000C3EC5630 (File and line number not available): ntdll.dll!RtlAllocateHeap
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\newaop.cpp (7): MySQLTrials.exe!operator new[]
0x00000000DF32199C (File and line number not available): MySQLTrials.exe!sql::mysql::MySQL_ResultBind::bindResult + 0xA0C bytes
0x00000000DF321379 (File and line number not available): MySQLTrials.exe!sql::mysql::MySQL_ResultBind::bindResult + 0x3E9 bytes
0x00000000DF313F69 (File and line number not available): MySQLTrials.exe!sql::mysql::MySQL_Prepared_ResultSet::MySQL_Prepared_ResultSet + 0x169 bytes
0x00000000DF2EC0E1 (File and line number not available): MySQLTrials.exe!sql::mysql::MySQL_Prepared_Statement::executeQuery + 0x1F1 bytes
e:\mysql\mysql.cpp (33): MySQLTrials.exe!wmain + 0x13 bytes
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c (240): MySQLTrials.exe!__tmainCRTStartup + 0x19 bytes
f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c (164): MySQLTrials.exe!wmainCRTStartup
0x00000000C1CF167E (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0x1A bytes
0x00000000C3EDC3F1 (File and line number not available): ntdll.dll!RtlUserThreadStart + 0x21 bytes
Visual Leak Detector detected 119 memory leaks (640915 bytes).
Largest number used: 697643 bytes.
Total allocations: 837447 bytes.
Visual Leak Detector is now exiting.
Question:
Why do we see leaks at line MySQL.cpp (23):
pConnection = driver->connect("tcp://127.0.0.1:3306", "username", "password");
and MySQL.cpp (33)
pResultSet= m_pPreparedStatement->executeQuery();
despite we delete pResultSetand pConnection? Why do we need to delete pPreparedStatement as well to free result set?
What I can deduce from your statement, you are already freeing the connection with the statement:
delete pConnection
That means when you initialize the PreparedStatement again, you're have to initialize it like:
pPreparedStatement = pConnection->prepareStatement(...)
Therefore, you don't free the PreparedStatement object but only reuse the object. C++ does not have garbage collection by default, and you have to free objects when you no longer need them.
In order to have something close to Java's garbage collection, I'd advice you use either a shared_ptr or scoped_ptr which will free your memory when your objects are no longer needed.
You can checkout Boost C++ Libraries for a comprehensive tutorial on how to free memory dynamically. For example:
boost::scoped_ptr<sql::Connection> con(driver->connect(host, user,pass));
boost::scoped_ptr<sql::Statement> stmt(con->createStatement());
That way you don't need to remember to call delete on your objects as memory will be freed when the object is no longer in scope. But you have to include boost libraries.
#include <boost/scoped_ptr.hpp>
It's obvious in my opinion that the prepared statement contains the query string which is used to retrieve the resultset, that said it looks clear to me that the prepared statement is in a separate location of memory than the resultset, you can also deduce that from your code:
sql::ResultSet *pResultSet = NULL;
sql::PreparedStatement *pPreparedStatement = NULL;
therefore when the connection goes out of scope or is released the memory allocated for your prepared statement is still tied to that object containing that query, but since the connection object is freed you have no longer access to that part of your memory, and because it isn't freed like you where supposed to your operating system still has marked that portion of memory flagged as in use, resulting in a memory leak.
Why go through all that trouble finding out why you have free the memory to prevent a memory leak, which seems obvious to me, in stead of just adding one line of code:
delete pPreparedStatement.
as described in the accompanying documentation, or as I like to do it, encapsulate it in a class (eg. dbConnection) and let de destructor do all the work so you only have to write the statement in one location and can forget it after that. It's easy and clean practice and it teaches to write clean and leak free code.
Adding garbage collection through extra libraries just gets you sloppy and makes for buggy software in my opinion, it's generally not worth the trouble and can give tons of overhead while you really have to add one line of code per object to delete.
Besides I think that kind of laziness will eventually bite you in the ass when some garbage gets deleted while there is still need for the data it's containing but the garbage collection comes to early, or in fact you let your object go out of scope to soon and you have to find out why your app is constantly crashing in particular situations.
When you do all the work yourself it may look more troublesome at start but in the end you'll be glad that you can correct that kind of coding errors in seconds in stead of having long antagonizing sessions of bug hunting only to find you somewhere have one small error in your code.
Select the version of MySQL you are using and
SEARCH for 'Prepared SQL Statement Syntax'.
You will find 3 specific activities and Syntax examples
A) PREPARE Syntax
B) EXECUTE Syntax
C) DEALLOCATE Syntax
that may work out better for you than ResultSet object deletion
and you will likely see your resources have been released, when DEALLOCATE has completed.
I'm trying to build a AS3 socket server that can handshake with html5 websockets. I've base my code on this link https://datatracker.ietf.org/doc/html/draft-ietf-hybi-thewebsocketprotocol-17
This is what i have using the same values as the example in the link:
import com.dynamicflash.util.Base64;
import com.adobe.crypto.SHA1;
function getKey():void{
var key:String = "dGhlIHNhbXBsZSBub25jZQ==258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
key = SHA1.hash(key);
key = Base64.encode(key);
trace(key);
//traces YjM3YTRmMmNjMDYyNGYxNjkwZjY0NjA2Y2YzODU5NDViMmJlYzRlYQ== instead of s3pPLMBiTxaQ9kYGzzhZRbK+xOo="
}
Now the example states that the output should be :
Concretely, if as in the example above, |Sec-WebSocket-Key| header field had the value "dGhlIHNhbXBsZSBub25jZQ==", the server would concatenate the string "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" to form the string "dGhlIHNhbXBsZSBub25jZQ==258EAFA5-E914-47DA-95CA-C5AB0DC85B11". The server would then take the SHA-1 hash of this, giving the value 0xb3 0x7a 0x4f 0x2c 0xc0 0x62 0x4f 0x16 0x90 0xf6 0x46 0x06 0xcf 0x38 0x59 0x45 0xb2 0xbe 0xc4 0xea. This value is then base64-encoded (see Section 4 of [RFC4648]), to give the value "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="
Am i missing something ??
Its a while since I've even read any ActionScript but shouldn't you replace
key = SHA1.hash(key);
key = Base64.encode(key);
with
key = SHA1.hashToBase64(key);
? The current code converts the sha1 hash (a byte array) into a string but its the original byte array you need to pass into the base64 encoder.
Let me know if this is of any help:
https://github.com/childoftv/as3-websocket-server