Why we need to write u8NAL first to .h264 file before writing stream data - h.264

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.

Related

How do I get nbit types from fread?

I have a file that is a concatenation of K, 17-bit, little endian, unsigned integers. In Matlab I am able to use fread(fd, K, 'bit17', 'ieee-le'). How do I read 17 bits off of a file descriptor in octave?
You can read the file byte by byte then use bitget to get the binary representation of data and then convert the binary representation to decimal numbers.
nbits = 17;
fd = fopen("myfile","rb");
bytes = fread(fd,Inf,"uint8=>uint8");
n = numel(bytes);
bits = false(8, n);
for k = 1:8
bits(k,:)=bitget(bytes,k);
end
count = floor(n * 8/nbits);
val = 2.^(0:nbits-1) * reshape(bits(1:count*nbits),nbits,[]);

h264: Add user unregistered SEI message

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.

Prepared statements: Memory stays allocated to result set despite we delete it

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.

How to generate ccFPSImage.c file in cocos2d-x

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".

AS3 Websocket Handshake

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