What's new

Encoding scheme for digcap.dav

bit-twiddler

n3wb
I am sorry if this information has been covered in the past, but I decided to take crack at figuring out the encoding scheme for digicap.dav after playing around with hiktools last night. I figured that I would start by looking to see if the author was using an XOR-based encoding scheme. I used XOR-based encoding algorithms to obfuscate static data as well as code in some of the products that I developed earlier in my career. An XOR-based encoder does not stop a determined hacker or competitor from reverse engineering one's code, but it does make the task painful enough that the less determined move onto easier to crack puzzles. The beauty of XOR is that it is symmetrical, that is, if we perform the operation A = B XOR C , then we can recover B by XORing C with A. XOR encoding/decoding is very fast.

Here's what I obtained by XORing the first 40 bytes of the digicap.dav file in the Chinese 5.3 to English 5.2.5 downgrader package with the values returned by hiktools.

BA CD BC FE D6 CA DD D3 BA B9 A3 AB BF CB B5 BE CD BC FE D6 CA DD D3 BA B9 A3 AB BF CB B5 BE BA BC FE D6 CA

Now, what we are hoping to find in this string are repeats. The places where the string repeats tells us something about the length of an XOR encoder's seed value.

BA CD BC FE D6 CA DD D3 BA B9 A3 AB BF CB B5
BE CD BC FE D6 CA DD D3 BA B9 A3 AB BF CB B5
BE BA BC FE D6 CA

As one can clearly see, we start to obtain a repeating pattern after 15 bytes; hence, we know that we are a) dealing with an XOR encoder, and b) the first 15 bytes are part of the encoder's seed value (a.k.a. the key). If we examine the second line above, we discover that it differs in one place when compared with the line above it; namely, the first byte, and the difference is 0x04. That's another key to the algorithm. The first six bytes of the third string differ from the second string in the second byte. If I did not make a data entry error, this pattern tells me that we may be dealing with an encoder that is modifying the key using a shift plus XOR or AND/OR modifier that is folding in bits from some other source. If we XOR all of the header bytes in the raw data with the decoded bytes, the XOR encoding algorithm should reveal itself.

Stay tuned...

Last edited by a moderator:

bit-twiddler

n3wb
I left my decoder test code at work, but I noticed something about the data in my posting a few minutes ago. It appears that the encoding/decoding algorithm is even simpler than I originally assumed. Upon closer inspection, the seed value (a.k.a. key) is actually 16 bytes long, not 15 bytes long. No bit fold-in occurs. What happens is that the entire key is circularly shifted leftwards an entire byte after encoding/decoding 16 bytes. If I am correct, the key value will repeat after 256 bytes have been processed.

Key for 1st 16 byte block (block 0): BA CD BC FE D6 CA DD D3 BA B9 A3 AB BF CB B5 BE
Key for 2nd 16 byte block (block 1): CD BC FE D6 CA DD D3 BA B9 A3 AB BF CB B5 BE BA
Key for 3rd 16 byte block (block 2): BC FE D6 CA DD D3 BA B9 A3 AB BF CB B5 BE BA CD
Key for 4th 16 byte block (block 3): FE D6 CA DD D3 BA B9 A3 AB BF CB B5 BE BA CD BC
Key for 5th 16 byte block (block 4): D6 CA DD D3 BA B9 A3 AB BF CB B5 BE BA CD BC FE
Key for 6th 16 byte block (block 5): CA DD D3 BA B9 A3 AB BF CB B5 BE BA CD BC FE D6
Key for 7th 16 byte block (block 6): DD D3 BA B9 A3 AB BF CB B5 BE BA CD BC FE D6 CA
Key for 8th 16 byte block (block 7): D3 BA B9 A3 AB BF CB B5 BE BA CD BC FE D6 CA DD
Key for 9th 16 byte block (block 8): BA B9 A3 AB BF CB B5 BE BA CD BC FE D6 CA DD D3
Key for 10th 16 byte block (block 9): B9 A3 AB BF CB B5 BE BA CD BC FE D6 CA DD D3 BA
Key for 11th 16 byte block (block 10): A3 AB BF CB B5 BE BA CD BC FE D6 CA DD D3 BA B9
Key for 12th 16 byte block (block 11): AB BF CB B5 BE BA CD BC FE D6 CA DD D3 BA B9 A3
Key for 13th 16 byte block (block 12): BF CB B5 BE BA CD BC FE D6 CA DD D3 BA B9 A3 AB
Key for 14th 16 byte block (block 13): CB B5 BE BA CD BC FE D6 CA DD D3 BA B9 A3 AB BF
Key for 15th 16 byte block (block 14): B5 BE BA CD BC FE D6 CA DD D3 BA B9 A3 AB BF CB
Key for 16th 16 byte block (block 15): BE BA CD BC FE D6 CA DD D3 BA B9 A3 AB BF CB B5

The key sequence repeats when the block number mod 16 = 0 (e.g., 0, 16, 32, 48, 64, 80, 96 ...)

Key for 17th 16 byte block (block 16): BA CD BC FE D6 CA DD D3 BA B9 A3 AB BF CB B5 BE

bit-twiddler

n3wb
Actually, I am kind of new to Hikvision cameras, and quite frankly, I would have been happy using my Hivision cameras like appliances if I had not unknowingly purchased a re-flashed Chinese camera off of Amazon. I pulled an all-nighter on Sunday night after attempting to re-flash the camera and discovering that I had a modded Chinese camera. My other 2032s were acquired from a friend who orders from Anixter. They were left over from a job that he did for a budget conscious customer. Anixter is an authorized Hikvision USA distributor; therefore, they are U.S. market cameras.

Last edited by a moderator:

alastairstevenson

Staff member
Yes, you could argue that for most end-users there's limited benefit in messing around with the insides of these things.
In some ways it's just curiosity or for the intellectual challenge - not any monetary gain such as extra options activation you'd otherwise have to pay for.
But when a manufacturer puts up obstacles to limit how people can use their products purchased on the open market that's always an incentive to try to knock those obstacles down.
And as a spin-off help others who as in your experience above quite innocently apply an update, as one can, and discover a bad side effect.

bit-twiddler

n3wb
Concur! The people who are being hurt by Hikvision's actions are not those who are selling re-flashed cameras or those who knowingly purchase re-flashed cameras. It's consumers who unaware that many Hikvision cameras are grey market items that have been re-flashed with hacked code. I am now motivated to do my best to ensure that no one is ever left with a bricked camera in a critical surveillance situation. The reason why I pulled an all-nighter is because I could not afford to have that camera down. It replaced a different camera that went belly up.

bit-twiddler

n3wb
How would you like a bigger challenge?
The newer NVR firmware also has the contents of the files encoded.
As a for example, if you take a 3.3.2 version from here http://www.hikvisioneurope.com/portal/index.php?dir=Product Firmware/Recorder/DS-7600NI-E1(E2) 7700NI-E4/
'split' it with Hiktools (or just cut the 108 byte header off it) and mount the resulting 'cramfs.img' to extract the contents, you can see that the files themselves are encoded.
This defeats the ability to change scripts such as initrun.sh or add new ones.
Maybe I am missing something here, but the files in the compressed ROM file system (cramfs.img) are not encoded to obfuscate information like the header is in the camera digicap.dav file. They are merely tarballs that have been compressed with the lzma (Lempl-Ziv-Markov) algorithm or the gzip (Lempl-Ziv 1977) algorithm. They can be decompressed/re-compressed using off-the-shelf tools on Windows (Cygwin) and with flags using the tar command on Linux. We are looking at low hanging fruit from a security point of view.

Last edited by a moderator:

whoslooking

IPCT Contributor
So from this we understand the key is hidden within the firmware update, as updating from an older firmware would fail in the same way.

bit-twiddler

n3wb
Okay gentlemen, Hikvision is still using an XOR-based encoder (technically, a coder-decoder). I have been able to derive the first 1024 bytes of the XOR sequence using well-known cryptanalysis techniques. I performed a frequency count on the sequence to see what kind of distribution we are seeing. Sadly, the algorithm driving this key sequence is much more random than the one used on digicap.dav.

If you want to see the first 1024 bytes of the key sequence in action and know C, the byte sequence shown below when XORed byte-by-byte with the 3.3.2 start.sh will reveal the first 1024 bytes of the file.

0x0C, 0xC3, 0x90, 0x88, 0xA6, 0xED, 0xD8, 0xF3, 0xBB, 0xBA, 0xAE, 0xC7, 0x7B, 0x5A, 0x29, 0x87,
0xFC, 0x40, 0x56, 0x60, 0x93, 0xEB, 0x6F, 0xF1, 0xAB, 0x76, 0x75, 0x13, 0xA5, 0xA8, 0xFB, 0xBE,
0xB1, 0xBE, 0xEA, 0xF6, 0x46, 0x51, 0x3E, 0x83, 0x88, 0x45, 0xE4, 0xAE, 0x3B, 0x54, 0x34, 0xFD,
0xAD, 0xE5, 0xDD, 0xB1, 0x61, 0xB7, 0xB7, 0x77, 0x35, 0xD7, 0x02, 0xB7, 0xE0, 0x51, 0x1F, 0x79,
0xFA, 0x4B, 0xB7, 0x7A, 0xBB, 0xA6, 0x0E, 0x75, 0x99, 0x23, 0x56, 0xB5, 0x74, 0x44, 0x84, 0x1D,
0x1C, 0x22, 0x55, 0x36, 0x3F, 0xD0, 0x6A, 0x27, 0xEF, 0x06, 0x80, 0x89, 0x45, 0x3D, 0x13, 0x3B,
0x0B, 0xE7, 0x5F, 0x5C, 0x2C, 0x3D, 0x9A, 0x8F, 0x7F, 0x2B, 0xD2, 0x2A, 0xA0, 0x6F, 0x78, 0x66,
0x6F, 0x68, 0xD7, 0xAA, 0xC8, 0x3E, 0x78, 0xCC, 0x5C, 0x76, 0x55, 0xAF, 0x4C, 0xAF, 0x56, 0xF3,
0xAC, 0x75, 0xD3, 0xAE, 0x6E, 0x44, 0xCD, 0x9B, 0x93, 0x9B, 0x9D, 0x7C, 0xA4, 0xA0, 0xAC, 0xBD,
0x5B, 0xD4, 0x9E, 0xE2, 0x85, 0x26, 0x72, 0xA7, 0x6C, 0x0E, 0x19, 0x01, 0x23, 0x52, 0xBF, 0x94,
0x7A, 0xB0, 0xAC, 0x09, 0xEB, 0xAE, 0x9C, 0xA0, 0x9F, 0xE8, 0x34, 0x34, 0x73, 0xF0, 0x7D, 0xEC,
0xB7, 0x20, 0x3E, 0x85, 0x48, 0x9E, 0x9D, 0xDF, 0x66, 0x28, 0x01, 0x25, 0xDB, 0x43, 0x06, 0xC6,
0x57, 0x99, 0x56, 0x7F, 0x5E, 0xF1, 0xC7, 0xCA, 0x00, 0xF8, 0x7F, 0xB7, 0x5D, 0x28, 0xA7, 0xEC,
0x47, 0xB0, 0x64, 0x24, 0x70, 0x82, 0x98, 0x9F, 0xCC, 0x99, 0xFE, 0xFC, 0x93, 0x03, 0xF2, 0x15,
0xEF, 0xF3, 0xC1, 0xB4, 0x08, 0x6F, 0x3E, 0x54, 0x31, 0xC3, 0xB4, 0xA6, 0xCB, 0xDD, 0xB4, 0x47,
0x08, 0xE9, 0x13, 0xB8, 0x10, 0x29, 0xA6, 0xAE, 0x56, 0xFE, 0x7E, 0x6D, 0x63, 0xCC, 0x96, 0xD6,
0x80, 0x9E, 0xE3, 0xF4, 0xD8, 0x58, 0xFB, 0x0E, 0xCA, 0x94, 0x58, 0xBE, 0x78, 0x67, 0xD0, 0x6C,
0xC2, 0xE1, 0x70, 0xEA, 0x83, 0xA1, 0xE0, 0x6D, 0xB7, 0x2F, 0xC0, 0xA9, 0x78, 0xDD, 0xB2, 0x3A,
0x58, 0xB6, 0x71, 0xF8, 0x1F, 0x25, 0xE7, 0xE0, 0x52, 0xEF, 0x06, 0x62, 0x79, 0xC4, 0x9E, 0xD9,
0xDB, 0x97, 0xFE, 0xB9, 0xC5, 0x16, 0xF5, 0x47, 0xBA, 0xE9, 0x51, 0x24, 0xF5, 0xF0, 0x1F, 0xB4,
0x2C, 0x97, 0x17, 0xC4, 0x52, 0x06, 0x09, 0xB5, 0xB0, 0xBA, 0x03, 0xDD, 0xE6, 0xD9, 0x2B, 0x06,
0x09, 0xC7, 0x8D, 0x36, 0xB7, 0x0E, 0x5C, 0xCE, 0x0D, 0x54, 0xD0, 0xD2, 0xD3, 0x1F, 0x1C, 0x37,
0xC4, 0xED, 0x24, 0xBA, 0xDE, 0xBD, 0xEE, 0x68, 0xD0, 0xB5, 0x98, 0xE3, 0x11, 0xC1, 0xDD, 0x49,
0x2A, 0xD6, 0x42, 0xB0, 0xE4, 0xEE, 0xDF, 0xD9, 0x7C, 0xC9, 0xA7, 0x1A, 0xC9, 0xBF, 0xFE, 0x99,
0x0F, 0x8B, 0x57, 0x14, 0xD3, 0x44, 0x2A, 0xC2, 0xCB, 0xED, 0x0E, 0xF5, 0xDB, 0xF5, 0xAE, 0x77,
0x9F, 0xB4, 0x92, 0xAB, 0x1F, 0x91, 0x89, 0x4E, 0x3E, 0xC7, 0x46, 0xB1, 0xED, 0xE3, 0xA0, 0xA0,
0x53, 0xAA, 0x7E, 0xF6, 0xEC, 0x58, 0x75, 0xCE, 0xA0, 0x34, 0x56, 0xE4, 0x55, 0x95, 0x95, 0x36,
0x3B, 0x3D, 0xB4, 0xA0, 0xB3, 0xBD, 0xCD, 0x36, 0xDB, 0xE6, 0x0E, 0x54, 0x7A, 0x85, 0x68, 0xD3,
0x84, 0x3E, 0xD7, 0x4B, 0xD3, 0x3D, 0x11, 0x9A, 0x1A, 0x98, 0x57, 0x3D, 0x4F, 0xBF, 0xD4, 0x9A,
0x3A, 0x5A, 0x26, 0xA2, 0x09, 0x92, 0xC9, 0x9F, 0x97, 0xBE, 0x08, 0x27, 0x98, 0x28, 0xFC, 0x38,
0xEC, 0x28, 0xDE, 0x0B, 0xF3, 0x4C, 0xDD, 0x04, 0x16, 0x9D, 0x4E, 0x70, 0x05, 0xF8, 0xDA, 0x87,
0x1D, 0xB6, 0x78, 0xE7, 0x02, 0x6F, 0xA6, 0xF5, 0xF3, 0x35, 0x4E, 0xFE, 0xF3, 0x7C, 0x51, 0xFD,
0x5D, 0x9F, 0x55, 0x35, 0x05, 0xF8, 0xDC, 0x81, 0xEE, 0x73, 0xC6, 0x90, 0x29, 0xA6, 0x89, 0x1E,
0x95, 0xFC, 0xBE, 0x9E, 0x55, 0x85, 0xBF, 0x08, 0x11, 0xFE, 0x60, 0xAD, 0x3F, 0x52, 0x4C, 0x04,
0x1F, 0x6E, 0x68, 0x2E, 0x08, 0x41, 0x2B, 0x6C, 0xEF, 0x20, 0xCD, 0xBB, 0xFE, 0x46, 0x80, 0x0B,
0x41, 0x0F, 0x90, 0x20, 0xA8, 0x90, 0xF6, 0xE4, 0x7F, 0x08, 0x5E, 0x66, 0x7A, 0xA0, 0x70, 0x69,
0x57, 0xED, 0x78, 0xE5, 0x52, 0x38, 0xA9, 0xE7, 0xB5, 0x69, 0x0B, 0xA2, 0xF9, 0x39, 0x5E, 0xBA,
0x5C, 0x9B, 0x17, 0x38, 0x43, 0xE3, 0xDC, 0xC4, 0xE9, 0x07, 0x07, 0x84, 0x60, 0xB2, 0x97, 0xFF,
0x4A, 0x7D, 0xEE, 0xE8, 0x59, 0x0C, 0x1D, 0x4E, 0xC9, 0xAD, 0x65, 0xE8, 0xDD, 0xDF, 0x8B, 0x72,
0xE3, 0xE8, 0x70, 0x56, 0x57, 0xC2, 0x41, 0x73, 0xE2, 0x55, 0x5B, 0x99, 0xE7, 0x70, 0x64, 0xEE,
0x1A, 0x6D, 0xF2, 0x50, 0xCC, 0x13, 0xFE, 0x54, 0xFF, 0x44, 0x7D, 0xBD, 0x94, 0x93, 0xDD, 0x7C,
0xAF, 0x2F, 0x17, 0xA3, 0x79, 0x3A, 0xB5, 0x5D, 0xE3, 0x3C, 0xB0, 0xEF, 0x6A, 0x42, 0x9E, 0xC6,
0x37, 0x85, 0x0B, 0x02, 0xCD, 0x9B, 0x60, 0x81, 0x1C, 0x79, 0x11, 0x65, 0xEF, 0xD1, 0xB5, 0x19,
0xFA, 0x2A, 0xE4, 0xE1, 0x2E, 0x5D, 0xCD, 0xE3, 0x5B, 0xF7, 0xD6, 0xAC, 0x42, 0xC9, 0x95, 0x3F,
0x17, 0xFD, 0x39, 0xA0, 0x45, 0x77, 0xE8, 0xAE, 0xE4, 0x7D, 0x8F, 0xC0, 0x22, 0xAA, 0xA5, 0xDC,
0x59, 0x9E, 0x3C, 0xB0, 0x52, 0xF3, 0xBC, 0x1C, 0x6A, 0x42, 0xD0, 0x2C, 0xE7, 0xCA, 0xA4, 0xFC,
0x52, 0x3D, 0xC4, 0x76, 0x15, 0xB8, 0x3A, 0xFA, 0xFD, 0x8E, 0x05, 0xFB, 0xBA, 0x1D, 0x19, 0xF2,
0x93, 0x97, 0x8E, 0xFA, 0x5B, 0x77, 0xF1, 0x72, 0xF2, 0x0A, 0xA6, 0x5D, 0x39, 0xD4, 0x46, 0x9F,
0xD9, 0x5B, 0x8E, 0xAB, 0x88, 0xDE, 0x9D, 0xDE, 0xF4, 0xB1, 0x1C, 0x7F, 0xE2, 0xCD, 0x95, 0x99,
0x03, 0x82, 0x1F, 0x84, 0xFB, 0x79, 0xD2, 0x07, 0x82, 0xCA, 0x98, 0xB0, 0x18, 0x9E, 0xC0, 0x87,
0x7D, 0x0E, 0x1E, 0xA3, 0xF6, 0x06, 0xF9, 0xDC, 0x6A, 0x0C, 0xAC, 0xE8, 0x86, 0xD2, 0x14, 0x2A,
0xFE, 0x44, 0x20, 0x89, 0x98, 0x83, 0x91, 0x1E, 0x19, 0x87, 0xA8, 0x2D, 0xE0, 0x43, 0x35, 0xF2,
0x83, 0xEA, 0x6B, 0xF5, 0xC8, 0xFA, 0xE0, 0x6F, 0x01, 0xB0, 0xD5, 0xD6, 0x35, 0x7C, 0x22, 0xE8,
0x64, 0x11, 0x95, 0xE9, 0xD5, 0x65, 0x37, 0x2D, 0x8F, 0x53, 0xAC, 0x37, 0xCE, 0xEB, 0xA6, 0xC0,
0x78, 0x0F, 0xE6, 0x5F, 0xEF, 0x59, 0x27, 0x44, 0x8F, 0x25, 0xD8, 0x8D, 0xC8, 0xA6, 0x9D, 0xDE,
0x7E, 0x1C, 0x9F, 0xE1, 0x82, 0x9A, 0xF7, 0x8A, 0x94, 0xC3, 0xCB, 0xA5, 0x45, 0xD9, 0x64, 0x5C,
0x93, 0x49, 0x4E, 0x36, 0x70, 0xFE, 0x0A, 0xEE, 0x60, 0x3C, 0x43, 0x2B, 0x6C, 0x71, 0x17, 0xE1,
0x36, 0x45, 0xA4, 0x61, 0xB2, 0xD8, 0x0E, 0x79, 0x3E, 0x16, 0xA2, 0xBF, 0x99, 0xC9, 0xD5, 0x97,
0xFB, 0x22, 0x54, 0xF9, 0x13, 0xDE, 0x4B, 0x2F, 0xD7, 0x0F, 0x17, 0x60, 0x36, 0xFE, 0x09, 0xEA,
0x23, 0x52, 0x02, 0x73, 0x7F, 0x69, 0x6F, 0xA4, 0xB2, 0x1C, 0x1A, 0xC6, 0xE4, 0x89, 0xD6, 0x31,
0x88, 0xB5, 0x30, 0x6E, 0x08, 0xDE, 0xD0, 0xD4, 0xE8, 0x24, 0xF7, 0x07, 0x51, 0x29, 0x6E, 0xA6,
0xD2, 0xB1, 0xD7, 0xEF, 0x70, 0xA2, 0x9A, 0xD6, 0xEF, 0xF6, 0x6C, 0x61, 0xB6, 0x9B, 0xE3, 0x0A,
0x0D, 0x9F, 0xEC, 0xBE, 0x2A, 0x5E, 0x82, 0x11, 0x6B, 0x36, 0xCA, 0xC5, 0x52, 0xC5, 0x2B, 0xFE,
0x17, 0xCD, 0x46, 0x37, 0x06, 0xC1, 0x8A, 0x1B, 0xE6, 0xD4, 0x63, 0xA1, 0x36, 0x96, 0xF2, 0x3A

The sequence will eventually cycle around. However, given the fact that no apparent repeat occurs in 1024 bytes and the uneven distribution of byte values in the sequence means that we are dealing with something that either a) uses a very long key, or b) injects pseudo-randomness into the equation. Hikvision is upping their game, which means that we need to be careful about discussing a solution in the open, that is, if one is found. The digicap.dav solution is one thing. This cipher is more sophisticated. We sure as heck do not want Hikvision to raise the bar. I would prefer to avoid having to disassemble their code. I will do it if there is no other way, but I can think of a million things that I would rather do than wade through C compiler-generated ARM machine code.

Stay tuned...

alastairstevenson

Staff member
Interesting, again!
You make a good point:
we need to be careful about discussing a solution in the open
I'm sure Hikvision watch this quite lively public forum with some interest. Whether any of the changes they have made are a consequence of activities here would be fascinating to know.
Hopefully one of the things they take from it is that the community is not defrauding them of revenue, nor selling for gain their intellectual property.
If anything, activities will raise interest in their products, which I have to say are examples of pretty good engineering at very good prices.

bit-twiddler

n3wb
So from this we understand the key is hidden within the firmware update, as updating from an older firmware would fail in the same way.
The key and the algorithm are more than likely in the uImage file.

nayr

IPCT Contributor
this might help you out, its for Dahua's DAV files tho.. dunno bout hik's

Code:
``````/************************************************************************//* dhplay   Version:  3.34.0 			                                    */
/************************************************************************/

#ifndef _DHPLAY_H
#define _DHPLAY_H

#if (defined(WIN32) || defined(WIN64))
#ifdef dhplay_EXPORTS
#define PLAYSDK_API __declspec(dllexport)
#else
#define PLAYSDK_API __declspec(dllimport)
#endif
#define CALLMETHOD __stdcall
#define CALLBACK   __stdcall
#else
#define CALLMETHOD
#define CALLBACK
#define PLAYSDK_API extern "C"
#endif

#if defined(WIN32) || defined(WIN64)
#include <windows.h>
#else
#define BOOL		int
#define BYTE		unsigned char
#define PBYTE		BYTE*
#define LPBYTE		BYTE*
#define LONG		long
#define DWORD		unsigned long
#define WORD		unsigned short
#define COLORREF	DWORD
#define HDC			void*
#define HWND		void*
#define LPSTR		char*
#define UINT		unsigned int
#define TRUE		1
#define FALSE		0

typedef struct _SYSTEMTIME
{
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;

typedef struct tagRECT
{
LONG left;
LONG top;
LONG right;
LONG bottom;
}RECT;

#endif
#ifdef	__cplusplus
extern "C" {
#endif

/************************************************************************/
/* Macro Definition			                                                    */
/************************************************************************/

#define  FUNC_MAX_PORT					501		//max play channel amount

#define MIN_WAVE_COEF					-100
#define MAX_WAVE_COEF					100

#define TIMER_1							1		//Default timer. Accurate time. Support max 16 in one progress
#define TIMER_2							2		//Thread timer. No amount limit.

#define BUF_VIDEO_SRC					1		//Video source buffer
#define BUF_AUDIO_SRC					2		//Audio source buffer
#define BUF_VIDEO_RENDER				3		//Video data buffer after decoding
#define BUF_AUDIO_RENDER				4		//Audio data buffer after decoding

#define MAX_DISPLAY_WND					4		//Support max 4 zones in one time

#define DISPLAY_NORMAL					1		// In normal resolution
#define DISPLAY_QUARTER					2		//In 1/4 resolution

#define MAX_DIS_FRAMES					50		//Max decode buffer amount
#define MIN_DIS_FRAMES					6		//Mim decode buffer amount

#define BY_FRAMENUM						1		//In accordance with frame number
#define BY_FRAMETIME					2		//In accordance with time

#define SOURCE_BUF_MAX					1024*100000	//Max original buffer
#define SOURCE_BUF_MIN					1024*50		//Mim original buffer

#define STREAME_REALTIME				0		//The real-time has the highest priority
#define STREAME_FILE					1		//The fluency has the highest priority

#define T_AUDIO16						101
#define T_AUDIO8						100

#define T_UYVY							1
#define T_IYUV							3
#define T_RGB32							7

#define SUPPORT_DDRAW					1		//Support DIRECTDRAW. If not, player can not work
#define SUPPORT_BLT						2		//Display card support BLT operation. If not, player cannot work
#define SUPPORT_BLTFOURCC				4		//Display card BLT supports color switch
#define SUPPORT_BLTSHRINKX				8		//Display car BLT supports X axis zoom out
#define SUPPORT_BLTSHRINKY				16		//Display card BLT supports Y axis zoom out
#define SUPPORT_BLTSTRETCHX				32		//Display card BLT supports X axis zoom in
#define SUPPORT_BLTSTRETCHY				64		//Display card BLT supports Y axis zoom in
#define SUPPORT_SSE						128		//CPU support SSE command,Intel Pentium3 or higher support SSE command
#define SUPPORT_MMX						256		//CPU support MMX instruction set

#define PLAY_CMD_GetTime				1
#define PLAY_CMD_GetFileRate			2
#define PLAY_CMD_GetMediaInfo			3
#define PLAY_CMD_GetRenderNum			4
#define PLAY_CMD_GetRenderTime			5
#define PLAY_CMD_GetSrcTime				6

#define AVI_MEDIACHANGE_FRAMERATE		1
#define AVI_MEDIACHANGE_RESOLUTION		2

#define WATERMARK_DATA_TEXT				0
#define WATERMARK_DATA_JPEG_BMP			1
#define WATERMARK_DATA_FRAMEDATA		3

#define	DH_PLAY_NOERROR					0		// No error
#define DH_PLAY_PARA_OVER				1		//Illegal input parameter
#define DH_PLAY_ORDER_ERROR				2		//Callabck sequence is not right
#define DH_PLAY_TIMER_ERROR				3		// Failed to set multiple-media setup
#define DH_PLAY_DEC_VIDEO_ERROR			4		//Failed to decode video
#define DH_PLAY_DEC_AUDIO_ERROR			5		//Failed to decode audio
#define DH_PLAY_ALLOC_MEMORY_ERROR		6		//Failed to allocate meomory
#define DH_PLAY_OPEN_FILE_ERROR			7		//file operation failed
#define DH_PLAY_CREATE_OBJ_ERROR		8		//Failed to create thread events
#define DH_PLAY_CREATE_DDRAW_ERROR		9		//Failed to create directDraw
#define DH_PLAY_CREATE_OFFSCREEN_ERROR	10		//Failed to create back-end buffer
#define DH_PLAY_BUF_OVER				11		//Buffer is full. Input stream failed
#define DH_PLAY_CREATE_SOUND_ERROR		12		//Failed to create audio device
#define DH_PLAY_SET_VOLUME_ERROR		13		//Failed to set volume
#define DH_PLAY_SUPPORT_FILE_ONLY		14		//Become valid when play file
#define DH_PLAY_SUPPORT_STREAM_ONLY		15		//Become valid when play stream
#define DH_PLAY_SYS_NOT_SUPPORT			16		//System does not support. Decoder can work in Pentium 3 or higher
#define DH_PLAY_VERSION_INCORRECT		18		//Decoder and encoder version are not compatilble
#define DH_PLAY_INIT_DECODER_ERROR		19		//Failed to initialize decoder
#define DH_PLAY_CHECK_FILE_ERROR		20		//File is too short or bit stream can not be recognized
#define DH_PLAY_INIT_TIMER_ERROR		21		//Failed to initialize MMTimer
#define DH_PLAY_BLT_ERROR				22		//Bit copy failed
#define DH_PLAY_UPDATE_ERROR			23		//Failed to display overlay
#define DH_PLAY_MEMORY_TOOSMALL			24		//memory too small

/************************************************************************/
/*struct                                                            */
/************************************************************************/

typedef enum __tPicFormats
{
PicFormat_BMP = 0,						//BMP 32bit
PicFormat_JPEG,							//JPEG
PicFormat_JPEG_70,						//70% JPEG
PicFormat_JPEG_50,						//50% JPEG
PicFormat_JPEG_30,						//30% JPEG
PicFormat_JPEG_10,						//10% JPEG
PicFormat_BMP24,						//BMP 24bit
} tPicFormats;

typedef struct
{
LONG			nFilePos;				//Specify the frame offset position in the file
LONG			nFrameLen;				//Frame length
LONG			nFrameNum;				//Frame serial number
LONG			nFrameTime;				//Frame time
LONG			nErrorFrameNum;			//Error frame number
SYSTEMTIME*		pErrorTime;				//Error frame time
LONG			nErrorLostFrameNum;		//Error frame number
LONG			nErrorFrameSize;		//Error frame size
}FRAME_POS,*PFRAME_POS;

typedef struct
{
LONG			nWidth;					//Width, unit is pixel, 0 for audio data.
LONG			nHeight;				//height, 0 for audio data
LONG			nStamp;					//Time stamp info, unit is ms
LONG			nType;					//Video frame type,T_AUDIO16,T_RGB32,T_IYUV
LONG			nFrameRate;				//Image frame rate created during encoding
}FRAME_INFO;

typedef struct
{
#define FRAME_TYPE_VIDEO 0				//Video Frame
#define FRAME_TYPE_AUDIO 1				//Audio Frame
int				nFrameType;				//Frame Type
int				nFrameSeq;				//Frame serial number
int				nStamp;					//Frame time ,MilliSecond
int				nWidth;					//Width, unit is pixel, 0 for audio data.
int 			nHeight;				//height, 0 for audio data.
int				nFrameRate;				// Image frame rate created during encoding
int				nChannels;				//Audio Channel No.
int				nBitPerSample;			//Audio Sampling Bit
int				nSamplesPerSec;			//Audio Sampling Frequency
int				nReserved[64];			//Reserved Text
}FRAME_INFO_EX;

typedef struct
{
int				nFrameType;					//Frame type, definition as FRAME_INFO_EX nFrameType text

void*			pAudioData;				//Audio data if it is audio frame
int				nAudioDataLen;			//Audio Data Length

void*			pVideoData[3];			//as YUV components
int				nStride[3];				//as spacing among YUV components
int				nWidth[3];				//as width of YUV components
int				nHeight[3];				//as height of YUV components
int				nReserved[64];			//Reserved Text
}FRAME_DECODE_INFO;

typedef struct
{
int			lWidth;
int			lHeight;
int			lFrameRate;
int			lChannel;
int			lBitPerSample;
int			lSamplesPerSec;
}MEDIA_INFO;

typedef struct
{
char*			pDataBuf;				//Frame data
LONG			nSize;					//Frame size
LONG			nFrameNum;				//Frame serial number
BOOL			bIsAudio;				//Audio frame or not
LONG			nReserved;				//Reserved character
}FRAME_TYPE;

typedef struct
{
int		nLen;
char*	pBody;
int		nBodyLen;

int		nRet;				//0: decode 1://don't decode
char	reserved[128];
}DemuInfoEx;
typedef struct
{
int type;			// 1:VIDEO, 2:AUDIO, 3:DATA
int subtype;		// I Frame, BP Frame, PCM8, MS-ADPCM etc.
int encode;			// MPEG4, H264, STDH264
int sequence;		//

int width;
int height;

int rate;

// time information
int year;
int month;
int day;
int hour;
int minute;
int secode;
LONG timestamp;

int channels;
int bitspersample;
int samplespersecond;
}DEMUX_INFO;

/************************************************************************/
/*  Interface Definition	                                                            */
/************************************************************************/

//------------------------------------------------------------------------
// Function:	PLAY_OpenFile
// Description: Open file
// Parameter:	nPort,Port number
//		 sFileName,File name, The file size ranges from 4G to 4K
// Returns:		BOOL,TRUE--succeeded FALSE--failed
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_OpenFile(LONG nPort,LPSTR sFileName);

//------------------------------------------------------------------------
// Function:	PLAY_CloseFile
// Description: Close played file, call after PLAY_Stop
// Parameter:	nPort,Port number
// Returns:		BOOL,TRUE--succeeded FALSE--failed
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_CloseFile(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_OpenStream
// Description: Open stream interface (Just the same as open a file)
// Parameter: nPort,Port number
//		 pFileHeadBuf,It is not avialbale now. Please input NULL
//		 nSize,It is not avialbale now.Please input 0
//		 nBufPoolSize,Set storage data stream buffer size in the playe
//			The value ranges is
//			[SOURCE_BUF_MIN,SOURCE_BUF_MAX]. Usually it is 900*1024. Please increase the value if the data are not even
// Returns:		BOOL,TRUE--succeeded FALSE--failed
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_OpenStream(LONG nPort,PBYTE pFileHeadBuf,DWORD nSize,DWORD nBufPoolSize);

//------------------------------------------------------------------------
// Function:	PLAY_CloseStream
// Description: close data stream (just the same as close file), call after PLAY_Stop
// Parameter: nPort,Port number
// Returns:		BOOL,TRUE--succeeded FALSE--failed
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_CloseStream(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_Play
// Description: Start play. If it is playing, then return current play status to normal speed
// Parameter: nPort,Port number
//		 hWnd,Play window handle
// Returns:		BOOL,TRUE--succeeded FALSE--failed
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_Play(LONG nPort, HWND hWnd);

//------------------------------------------------------------------------
// Function:	PLAY_Stop
// Description: Stop Play
// Parameter: nPort,Port number
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_Stop(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_InputData
// Description: Input the stream data you get from the card. Enable stream and Then call PLAY_Play to input data
// Parameter: nPort,Port number
//		 nSize,Buffer size
// Returns:		BOOL,TRUE--succeeded FALSE--failed.There is no data. Usually the buffer is full
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_InputData(LONG nPort,PBYTE pBuf,DWORD nSize);

//------------------------------------------------------------------------
// Function:	PLAY_Pause
// Description: Pause/resume
// Parameter: nPort,Port number
//		 nPause,TRUE Pause,FLASE Resume
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_Pause(LONG nPort,DWORD nPause);

//------------------------------------------------------------------------
// Function:	PLAY_Fast
// Description: Fast play. There are 9 levels. The speeds are 1, 3, 6, 12, 25, 50, 75, 100, 125f/s respectively.
//		The speed escalates one level and support max 4 times in one callback.
//		You can call PLAY_Play to resume normal playback from current position
// Parameter: nPort,Port number
// Returns:		BOOL,TRUE--succeeded FALSE--failed
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_Fast(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_Slow
// Description: Slow play. The same as the above. Each time the speed lowers one level.
//		Support max callback 4 times. Pleae call PLAY_Play to resume normal play
// Parameter: nPort,Port number
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_Slow(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_OneByOne
// Description: Play frame by frame. Please call PLAY_ Play to resume normal playback
// Parameter:	nPort,Port number
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_OneByOne(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_SetPlayPos
// Description: Set relative position of file play pointer (unit :%)
// Parameter: nPort,Port number
//		 fRelativePos,The value ranges is [0, 100%]
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_SetPlayPos(LONG nPort,float fRelativePos);

//------------------------------------------------------------------------
// Function: PLAY_SetPlayDirection
// Description: Set play direction
// Parameter: nPort,Port number
//		 emDirection,Play direction:0,Forward ,1,BackWard
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_SetPlayDirection(LONG nPort, DWORD emDirection);

//------------------------------------------------------------------------
// Function:	PLAY_GetPlayPos
// Description: Get the relative position of the file player pointer.
// Parameter:	nPort,Port number
// Returns:		float,The value ranges is [0, 100%]
//------------------------------------------------------------------------
PLAYSDK_API float CALLMETHOD PLAY_GetPlayPos(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_SetFileEndMsg
// Description: Set the message to be sent when the end of the file is encountered
// Parameter: nPort,Port number
//       hWnd,The window to receive the message
//       nMsg,User defined message. When the end of the file is encountered, user may receive this message in the window process.
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_SetFileEndMsg(LONG nPort,HWND hWnd,UINT nMsg);

//------------------------------------------------------------------------
// Function:	PLAY_SetVolume
// Description: Set volume.
// Parameter: nPort,Port number
//		 nVolume,Volume value. The value ranges is [0, 0XFFFF]
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_SetVolume(LONG nPort,WORD nVolume);

//------------------------------------------------------------------------
// Function:	PLAY_StopSound
// Description: Disable audio
// Parameter:
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_StopSound();

//------------------------------------------------------------------------
// Function:	PLAY_PlaySound
// Description: Enable audio. There is only 1-ch audio in one time. System auto
//		disables previous audio if current audio is enabled.
//		Please note audio is disabled by default

// Parameter: nPort,Port number
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_PlaySound(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_GetFileTime
// Description: Get file total time length. Unit is second
// Parameter:	nPort,Port number
// Returns:		Total file time.
//------------------------------------------------------------------------
PLAYSDK_API DWORD CALLMETHOD PLAY_GetFileTime(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_GetPlayedTime
// Description: Get file played time. Unit is second
// Parameter: nPort,Port number
// Returns:		The file current played time
//------------------------------------------------------------------------
PLAYSDK_API DWORD CALLMETHOD PLAY_GetPlayedTime(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_GetPlayedFrames
// Description: Get the video frame amount that has been decoded
// Parameter:	nPort,Port number
// Returns:		The video frame amount that have been decoded
//------------------------------------------------------------------------
PLAYSDK_API DWORD CALLMETHOD PLAY_GetPlayedFrames(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_SetDecodeCallBack
// Description: Set callback function. It is to replace the displayed section in the player. You can control the displayed video.
//	Please call this function before PLAY_Play. This function becomes null when calling PLAY_Stop.
//	You need to reset when you call PLAY_Play the next time.The decode section does not control speed.
//	When you return from the callback function, the decoder will decode the next data. Please note before using this function;
//	you need to fully understand the video display and audio play. Otherwise, do not use this function casually!
// Parameter: nPort,Port number
//		 cbDec,Callback function pointer. It can not be null
//			nPort,Port number
//			pFrameDecodeInfo,Audio and video data after decoding
//			pFrameInfo,Image and audio information. Please refer to the following information
//			pUser,User defined parameter
// Returns:  	BOOL, TRUE--succeeded  FALSE--failed.
//------------------------------------------------------------------------
typedef void (CALLBACK* fCBDecode)(LONG nPort, FRAME_DECODE_INFO* pFrameDecodeInfo, FRAME_INFO_EX* pFrameInfo, void* pUser);
PLAYSDK_API BOOL CALLMETHOD PLAY_SetDecodeCallBack(LONG nPort, fCBDecode cbDec, void* pUser);

//------------------------------------------------------------------------
//------------------------------------------------------------------------
// Function:	PLAY_SetDisplayCallBack
// Description: Set video data callback. It can be used to snapshoot. You can set callback function
//		pointer of DisplayCBFun as null to stop callback. The callback function is valid all the time
//		once it is set, until the program exits. You can call this function at any time
// Parameter: nPort,Port number
//		 DisplayCBFun,Video data callback function. It can be null
//			nPort,Port number
//			pBuf,Video data buffer
//			nSize,video data size
//			nWidth,Image width. Unit is pixel
//			nHeight,Image height
//			nStamp,Time mark information. Unit is ms
//			nType,Data type. T_RGB32, T_UYVY. Please refer to macro definition
//			nReceaved,Reserved
//		 nUser,User-customized parameter
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
typedef void (CALLBACK* fDisplayCBFun)(LONG nPort,char * pBuf,LONG nSize,LONG nWidth,LONG nHeight,LONG nStamp,LONG nType, void* pReserved);
PLAYSDK_API BOOL CALLMETHOD PLAY_SetDisplayCallBack(LONG nPort, fDisplayCBFun DisplayCBFun, void* pUserData);

//------------------------------------------------------------------------
// Function:	PLAY_ConvertToBmpFile
// Description: Save the snapshoot image as BMP file.This switch will occupy CPU resources. Do not call this
//			function if you do not need to save image
// Parameter: pBuf,Image data buffer
//		 nSize,Image data size
//		 nWidth,Image width. Unit is pixel
//		 nHeight,Image height
//		 nType,Data type. T_RGB32, T_UYVY. Please refer to macro definition
//		 sFileName,File name. The file extension name is BMP
// Returns:		BOOL,TRUE--succeeded  FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_ConvertToBmpFile(char * pBuf,LONG nSize,LONG nWidth,LONG nHeight,LONG nType, char *sFileName);

//------------------------------------------------------------------------
// Function:	PLAY_ConvertToJpegFile
// Description: Convert YUV image data to jpeg format.
// Parameter: pYUVBuf,Image data buffer
//		 nWidth,Image width
//		 nHeight,Image height
//		 YUVtype,YUV data type. T_YV12,T_UYVY, ex.
//		 quality,Compress quality, (0, 100]
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_ConvertToJpegFile(char *pYUVBuf, LONG nWidth, LONG nHeight, int YUVtype, int quality, char *sFileName);

//------------------------------------------------------------------------
// Function:	PLAY_GetFileTotalFrames
// Description: Get total frame count
// Parameter:	nPort,Port number
// Returns:		DWORD,Total frame count
//------------------------------------------------------------------------
PLAYSDK_API DWORD CALLMETHOD PLAY_GetFileTotalFrames(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_GetCurrentFrameRate
// Description: get encode frame rate in current bit stream
// Parameter:	nPort,Port number
// Returns:		DWORD,Frame rate value when encoding current bit stream
//------------------------------------------------------------------------
PLAYSDK_API DWORD CALLMETHOD PLAY_GetCurrentFrameRate(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_GetPlayedTimeEx
// Description: Get file played time. Unit is ms
// Parameter:	nPort,Port number
// Returns:		DWORD,The file current played time
//------------------------------------------------------------------------
PLAYSDK_API DWORD CALLMETHOD PLAY_GetPlayedTimeEx(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_SetPlayedTimeEx
// Description: Set file play position according to the time. This interface takes a little bit longer
//				than the PLAY_SetPlayPos. But use time to control progress bar (working with PLAY_GetPlayedTime(Ex))
//				to make the progress bar smoothly
// Parameter:	nPort,Port number
//				nTime,Set the file play postion to the specified time. Unit is ms
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_SetPlayedTimeEx(LONG nPort,DWORD nTime);

//------------------------------------------------------------------------
// Description: Get current play frame serial number. PLAY_GetPlayedFrames is the total frame amount. If
//		the play position is the same, the return values of these two functions shall be very close,
//		unless data loss occurs
// Parameter:	nPort,Port number
// Returns:		Current play frame number.
//------------------------------------------------------------------------
PLAYSDK_API DWORD CALLMETHOD PLAY_GetCurrentFrameNum(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_SetStreamOpenMode
// Description: Set stream play mode. You need to set before playing
// Parameter:	nPort,Port number
//				nMode,STREAME_REALTIME Real-time mode (default);STREAME_FILE File mode.Real-time mode. It is suitable for network real-time mode.The
//						deocder card will begin decoding right now
//						File mode. It is suitable for you to input file data as stream
//						when PLAY_InputData() return FALSE, you need to wait and then input again.

// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_SetStreamOpenMode(LONG nPort,DWORD nMode);

//------------------------------------------------------------------------
// Function:	PLAY_GetSdkVersion
// Description: Get player SDK main version, sub-version and pack No.
// Parameter:
// Returns: The higher 16-bit represents current main version.9-16 represents sub-version. 1-8-bit represents sub-pack number.
//		For example:return value is 0x00030107 then you can see: main version is 3, sub-version is 1 and pack number is 7.
//------------------------------------------------------------------------
PLAYSDK_API DWORD CALLMETHOD PLAY_GetSdkVersion();

//------------------------------------------------------------------------
// Function:	PLAY_GetLastError
// Description: Get current error code. You can call this function to get error code if you fail to call one function
// Parameter: nPort,Port number
// Returns:		DWORD,Refer to Error type
//------------------------------------------------------------------------
PLAYSDK_API DWORD CALLMETHOD PLAY_GetLastError(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_RefreshPlay
// Description: Refresh to display. If you refresh when player is in pause mode, the window video
//		disappears. You can call this interface to get the video agaian. It is valid in pause and frame
//		by frame playback mode. System will return directly in other situations
// Parameter: nPort,Port number
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_RefreshPlay(LONG nPort);
// Function:	PLAY_GetPictureSize
// Description: Get the original image size from the bit stream and then adjust display window accordingly.
//		It does not need display card to support zoom function. It is very useful for those display cards
//		that does not support hardware zoom
// Parameter: nPort,Port number
//		 pWidth,Width of the original image. In PAL format CIF resolution it is 352
//		pHeight Height of the original image. In PAL format CIF resolution, the value is 288
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------

PLAYSDK_API BOOL CALLMETHOD PLAY_GetPictureSize(LONG nPort,LONG *pWidth,LONG *pHeight);

//------------------------------------------------------------------------
// Function:	PLAY_SetPicQuality
// Description: Set video quality. When it is in high quality the video is vivid, but the CPU comsuption
//		is high. When system is in multiple-channel play mode, you can set a little bit lower quality so
//		as to lower CPU comsuption. When you want to see one window in large zone, you can set it to high
//		quality to get excellent video effect
// Parameter: nPort,Port number
//		 bHighQuality,The video quality is the best when it is 1.The video quality is the lowest when it is o (default value.)
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_SetPicQuality(LONG nPort,BOOL bHighQuality);

//------------------------------------------------------------------------
// Function:	PLAY_PlaySoundShare
// Description: Play audio in share way. Play current channel audio while not disabling audio from other channels
// Parameter: nPort,Port number
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_PlaySoundShare(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_StopSoundShare
// Description: Disable audio in share way. PLAY_PlaySound and PLAY_StopSound are enable audio in
//		exclusive way. Please note, in one progress, all channels are required to use
//		same way to enable or disable audio
// Parameter: nPort,Port number
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_StopSoundShare(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_GetStreamOpenMode
// Description: Get stream mode type
// Parameter:	nPort,Port number
// Returns:		LONG,STREAME_REALTIME or STREAME_FILE.
//------------------------------------------------------------------------
PLAYSDK_API LONG CALLMETHOD PLAY_GetStreamOpenMode(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_GetVolume
// Description: To get current volume setup.
// Parameter: nPort,Port number
// Returns:		WORD,To get current volume value
//------------------------------------------------------------------------
PLAYSDK_API WORD CALLMETHOD PLAY_GetVolume(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_GetPictureQuality
// Description: Get current video quality
// Parameter:	nPort,Port number
//				bHighQuality TRUE high quality,FALSE low quality.
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_GetPictureQuality(LONG nPort,BOOL *bHighQuality);

//------------------------------------------------------------------------
// Function:	PLAY_GetSourceBufferRemain
// Description: Get sourcing buffer remained data in stream play mode
// Parameter:	nPort,Port number
// Returns:		DWORD,Current sourcing buffer size(byte)
//------------------------------------------------------------------------
PLAYSDK_API DWORD CALLMETHOD PLAY_GetSourceBufferRemain(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_ResetSourceBuffer
// Description: Clear the remained data in sourcing buffer in stream play mode
// Parameter: nPort,Port number
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_ResetSourceBuffer(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_OneByOneBack
// Description: Playback frame by frame. Each callback will return one frame.
//		You can call this function after creating the file index
// Parameter: nPort,Port number
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_OneByOneBack(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_SetFileRefCallBack
// Description: Set callback function pointer. Callback when establishing callback. To locate quickly
//		and accurately, system generates a file index when opening a file. This period may take a little
//		bit long. Its speed is about 40M/s, mainly because reading data from the HDD is slow. The index
//		establishment is operated in the background. The functions that need to use this index have to
//		wait until this process ends, while the other interfaces may not be affected
// Parameter: nPort,Port number
//		 pFileRefDone,Callback function pointer
//			nPort,Port number
//			nUser,User data
//		 nUser,User data
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
typedef void(CALLBACK *fpFileRefDoneCBFun)(DWORD nPort, void* pUserData);
PLAYSDK_API BOOL CALLMETHOD PLAY_SetFileRefCallBack(LONG nPort,
fpFileRefDoneCBFun pFileRefDoneCBFunc,
void* pUserData);

//------------------------------------------------------------------------
// Description: Specify the frame number in current position. Locate the play position according to the
//				frame number. The function need to be called back after creating the file index
// Parameter:	nPort,Port number
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// Function:	PLAY_GetKeyFramePos
// Description: Search I frame postion before the specified postion. The video decode begins from I frame.
//		If the saved file is not from I frame, then the data to the next I frame will be ignored. If you
//		need to get data from the file, you?°•e better get from I frame. But the end postion does not matter
//		since you may lose max 3 frames data.
// Parameter:	nPort,Port number
//				nValue,Current position. It can be time or frame number. Its type is appointed by nType
//				nType,Specify nValue type
//					If nType is BY_FRAMENUM, then nValue means frame number
//					If nType is BY_FRAMTIME, then nValue means time and unit is ms

//				pFramePos,I frame position information struct pointer.,?®∫??PFRAME_POS.
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_GetKeyFramePos(LONG nPort,DWORD nValue, DWORD nType, PFRAME_POS pFramePos);

//------------------------------------------------------------------------
// Function:	PLAY_GetNextKeyFramePos
// Description: Search I frame positon after the specified location
// Parameter: nPort,Port number
//		 nValue,Current position. It can be time or frame number. Its type is appointed by nType.
//		 nType,Specify nValue type
//			If nType is BY_FRAMENUM, then nValue means frame number
//			If nType is BY_FRAMTIME, then nValue means time and unit is ms
//		 pFramePos,I frame position information struct pointer.
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_GetNextKeyFramePos(LONG nPort,DWORD nValue, DWORD nType, PFRAME_POS pFramePos);

//------------------------------------------------------------------------
// Function: PLAY_SetDecCBStream
// Description: Set callback stream type when decoding
// Parameter: nPort,Port number
//		 nStream,1 Video stream;2 Audio stream;3 Composite stream.
// Returns: BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_SetDecCBStream(LONG nPort,DWORD nStream);

//------------------------------------------------------------------------
// Function:	PLAY_SetDisplayRegion
// Description: Set or add displayed zone. Support partial enlargement
// Parameter: nPort,Port number
//		 nRegionNum,Display zone serial number.
//				0~(MAX_DISPLAY_WND-1).
//				If nRegionNum is 0, it means the main display window
//		 pSrcRect,Partial displayed zone
//		 hDestWnd,Display window handle
//		 bEnable,Open (set) or close displayed zone
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_SetDisplayRegion(LONG nPort,DWORD nRegionNum, RECT *pSrcRect, HWND hDestWnd, BOOL bEnable);

//------------------------------------------------------------------------
// Function:	PLAY_GetRefValue
// Description: To get file index information so that you can use the information directly when you open
//		the same file the next itme. You need to create index to get information
// Parameter:	nPort,Port number
//				pBuffer,Index information
//				pSize,Input pBuffer size, output index information size.
//					Note: you can first set pSize=0,pBuffer=NULL, get the buffer size from the return value
//					of pSize and then allocate the enough buffer.Then you can callback again
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_GetRefValue(LONG nPort,BYTE *pBuffer, DWORD *pSize);

//------------------------------------------------------------------------
// Function:	PLAY_SetRefValue
// Description: Set file index. If there is file index, you do not need to call callback function
//		(PLAY_SetFileRefCallBack) and then directly input index information. Please note index
//		information and its length must be accurate
// Parameter:	nPort,Port number
//				pBuffer,Index information
//				nSize,Index information length
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_SetRefValue(LONG nPort,BYTE *pBuffer, DWORD nSize);

//------------------------------------------------------------------------
// Function:	PLAY_RigisterDrawFun
// Description: Register one callback function to get current surface device context. You can draw
//		(write) in the DC just as you do in client zone DC of the window. But this DC is not the client
//		zone DC of the window, it is the DC of Off-Screen in DirectDraw. Please note: This interface is
//		null if you use overlay surface. You can draw in the window. It will be displayed if it is not
//		a transparent color.
// Parameter: nPort,Port number
//		 DrawFun,Callback function handle
//			nPort,Port number
//			hDc,OffScreen, You can operate it just as operate the displayed window DC
//			nUser,User data
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
typedef void (CALLBACK* fDrawCBFun)(LONG nPort,HDC hDc, void* pUserData);
PLAYSDK_API BOOL CALLMETHOD PLAY_RigisterDrawFun(LONG nPort, fDrawCBFun DrawCBFun, void* pUserData);

//------------------------------------------------------------------------
// Function:	PLAY_ResetBuffer
// Description: Clear player buffer
// Parameter: nPort,Port number
//		 nBufType,Buffer type, Please refer to macro definition macro definition:
//			BUF_VIDEO_SRC 1
//			BUF_AUDIO_SRC 2
//			BUF_VIDEO_RENDER 3
//			BUF_AUDIO_RENDER 4
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_ResetBuffer(LONG nPort,DWORD nBufType);

//------------------------------------------------------------------------
// Function:	PLAY_GetBufferValue
// Description: To get player buffer size (frame amount or byte). You can use this interface to get the
//			data in the buffer so that you can estimate the network delaying time
// Parameter: nPort,Port number
//		 nBufType,®®???:
//			BUF_VIDEO_SRC 1
//			BUF_AUDIO_SRC 2
//			BUF_VIDEO_RENDER 3
//			BUF_AUDIO_RENDER 4
// Returns:		DWORD,Return different buffer values in accordance with various parameters. Sourcing buffer
//					returns byte and the buffer return the frame amount after decoding
//------------------------------------------------------------------------
PLAYSDK_API DWORD CALLMETHOD PLAY_GetBufferValue(LONG nPort,DWORD nBufType);

//------------------------------------------------------------------------
// Description: Adjust WAVE to adjust volume. The difference between this function and the PLAY_SetVolume is:
//			the function is to adjust audio data and only applies to current channel.
//			But PLAY_SetVolume is to adjust audio card volume and applies to the whole system.
//			This function has not realized yet.
// Parameter: nPort,Port number
//		 nCoefficient,Modified parameter.,The value ranges:[MIN_WAVE_COEF, MAX_WAVE_COEF]. 0 stands for no modification.
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_AdjustWaveAudio(LONG nPort,LONG nCoefficient);

//------------------------------------------------------------------------
// Function:	PLAY_SetAudioCallBack
// Description: Callback wave data after decoding audio frame
// Parameter: nPort,Port number
//		 funAudio,Audio callback function
//			nPort,Port number
//			pAudioBuf,Wave data buffer
//			nSize,Wave data length
//			nStamp,Time mark (ms)
//			nType,Audio type T_AUDIO16. Sampling rate 8000. single-channel. Each sampling spot is represented by 16-bit.
//			nUser,User defined data
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
typedef void (CALLBACK * fAudioCBFun)(LONG nPort, char * pAudioBuf, LONG nSize, LONG nStamp, LONG nType, void* pUserData);
PLAYSDK_API BOOL CALLMETHOD PLAY_SetAudioCallBack(LONG nPort, fAudioCBFun AudioCBFun, void* pUserData);

//------------------------------------------------------------------------
// Function:	PLAY_SetEncTypeChangeCallBack
// Description: Callback function to remind you when decoding format changes. Use it before opening a file
// Parameter: nPort,Port number
//		 funEncChange,Callback function
//			nPort,Port number
//			nUser,User data
//		 nUser,User data
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
typedef void(CALLBACK *fEncChangeCBFun)(LONG nPort, void* pUserData);
PLAYSDK_API BOOL CALLMETHOD PLAY_SetEncTypeChangeCallBack(LONG nPort, fEncChangeCBFun EncChangeCBFun, void* pUserData);

//------------------------------------------------------------------------
// Function:	PLAY_SetColor
// Description: Set video parameter. It becomes active once it is set
// Parameter:	nPort,Port number
//		 nRegionNum,Display zone. Please refer to PLAY_SetDisplayRegion. Please set it as o if there is only one display zone (usually it is 0)
//		 nBrightness,Brightness. Default value is 64. The value ranges from 0 to 128
//		 nContrast,Contratsness. Default value is 64. The value ranges from 0 to 128
//		 nSaturation,Saturation.Default value is 64. The value ranges from 0 to 128
//		 nHue,Hue.Default value is 64. The value ranges from 0 to 128
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_SetColor(LONG nPort, DWORD nRegionNum, int nBrightness, int nContrast, int nSaturation, int nHue);

//------------------------------------------------------------------------
// Function:	PLAY_GetColor
// Description: Get the corresponding color value. The parameter is the same as PLAY_SetColor
// Parameter:	nPort,Port number
//				nRegionNum,Display zone. Please refer to PLAY_SetDisplayRegion. Please set it as o if there is only one display zone (usually it is 0)
//				pBrightness,Brightness. Default value is 64. The value ranges from 0 to 128
//				pContrast,Contratsness. Default value is 64. The value ranges from 0 to 128.
//				pSaturation,Saturation.Default value is 64. The value ranges from 0 to 128
//				pHue,Hue.Default value is 64. The value ranges from 0 to 128
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_GetColor(LONG nPort, DWORD nRegionNum, int *pBrightness, int *pContrast, int *pSaturation, int *pHue);

//------------------------------------------------------------------------
// Function:	PLAY_SetEncChangeMsg
// Description: Set the message to be sent when decode format changes
// Parameter: nPort,Port number
//		 hWnd,The window to receive the message
//		 nMsg,User defined message. When encode format is changed during decoding, user may receive
//					this message in the window process
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_SetEncChangeMsg(LONG nPort,HWND hWnd,UINT nMsg);

//------------------------------------------------------------------------
// Function:	PLAY_CatchPic
// Description: Snapshoot, write picture data to specified file. PLAY_SetDisplayCallBack Call this function
//		when decoding video data and then you can process the video data (such as snapshoot). Keep calling
//		this callback function if there is continue decoding data. But LAY_CatchPic snapshoot one image
//		at one time and it can realize snapshoot in pause or frame by frame play mode. If you want to snapshoot
//		(one time for one image), please call PLAY_CatchPic. You can call PLAY_SetDisplayCallBack to get
//		video data in a period of time.
// Parameter: nPort,Port number
//		 sFileName,File name
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_CatchPic(LONG nPort,char* sFileName) ;

//------------------------------------------------------------------------
// Function:	PLAY_CatchPicEx
// Description: Snapshoot. Picture format could be specified as bmp or jpeg
// Parameter: nPort,Port number
//		 sFileName,File name
//		 ePicfomat,Picture format type refer to tPicFomats
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_CatchPicEx(LONG nPort,char* sFileName,tPicFormats ePicfomat);

//------------------------------------------------------------------------
// Function:	PLAY_SetFileEndCallBack
// Description: Set the end of file callback
// Parameter: nPort,Port number
//		 pFileEnd,Callback function pointer
//			nPort,Port number
//			nUser,User data
//		 nUser,User data
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
typedef void (CALLBACK *fpFileEndCBFun)(DWORD nPort, void* pUserData);
PLAYSDK_API BOOL CALLMETHOD PLAY_SetFileEndCallBack(LONG nPort, fpFileEndCBFun pFileEndCBFun, void* pUserData);

//------------------------------------------------------------------------
// Function:	PLAY_StartDataRecord
// Description: Begin record stream data. It applies to stream mode only. Call it after PLAY_Play
// Parameter: nPort,Port number
//		 sFileName,Record file name. If there is no exsiting folder in the name, then create a new folder
//		 idataType,0 Raw video stream;1 convert to avi;2 convert to asf
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_StartDataRecord(LONG nPort, char *sFileName, int idataType);

//------------------------------------------------------------------------
// Function: PLAY_WriteData
// Description: Save native stream
// Parameter: nPort,Port Number
//		 pBuf, Stream Buffer
//		 nSize,Buffer Size
// Returns: BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_WriteData(LONG nPort, PBYTE pBuf,DWORD nSize);

//------------------------------------------------------------------------
// Function:	PLAY_StopDataRecord
// Description: Stop recording stream data
// Parameter:	nPort,Port number
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_StopDataRecord(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_SetPlaySpeed
// Description: Change play speed
// Parameter:	nPort,nPort Number
//		        fCoff,Play Speed,Range[1/64~64.0],less than 1 play slowly£¨greater than 1 play quickly.
//			    when play speed is high enough ,it wil probally throw frame.
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_SetPlaySpeed(LONG nPort, float fCoff);

//------------------------------------------------------------------------
// Function:	PLAY_SetDemuxCallBack
// Description: Data callback after analysing the sourcing data
// Parameter: nPort,Port number
//		 DecCBFun,Analyse data callback pointer
//			nPort,Port number
//			pBuf,Data buffer
//			nSize,Data length
//			pParam,Frame information
//			nReserved,reserved
//			nUser,User defined data
//		 nUser,User defined data
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
typedef void (CALLBACK* fDemuxDecCBFun)(LONG nPort,char * pBuf,	LONG nSize,void * pParam,void* pReserved, void* pUserData);
PLAYSDK_API BOOL CALLMETHOD PLAY_SetDemuxCallBack(LONG nPort, fDemuxDecCBFun DecCBFun, void* pUserData);

//------------------------------------------------------------------------
// Function:	PLAY_QueryInfo
// Description: Information status search function. Now it can search current time and frame rate information
// Parameter: nPort,Port number
//		 cmdType,Specify status search type
//			PLAY_CMD_GetTime			get time information.Unit is ms
//			PLAY_CMD_GetFileRate		get frame rate information
//			PLAY_CMD_GetMediaInfo		get media information, sturct is MEDIA_INFO
//		 buf,Information buffer
//		 buflen,Buffer length
//		 returnlen,Valid data length
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_QueryInfo(LONG nPort , int cmdType, char* buf, int buflen, int* returnlen);

//------------------------------------------------------------------------
// Function:	PLAY_OpenAudioRecord
// Description: Enabel audio sampling operation
// Parameter: pProc,Audio sampling data callback pointer
//			pDataBuffer,Data callback pointer
//			DataLength,Callback data length
//			nUser,User data
//		 nBitsPerSample,Represent the bit for each sampling
//		 nSamplesPerSec,Sampling rate
//		 nLength,Data buffer length
//		 nReserved,Reserve
//		 nUser,User defined data
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
typedef void (CALLBACK *pCallFunction)(LPBYTE pDataBuffer, DWORD DataLength, void* pUserData);
PLAYSDK_API BOOL CALLMETHOD PLAY_OpenAudioRecord(pCallFunction pProc, LONG nBitsPerSample, LONG nSamplesPerSec, LONG nLength, LONG nReserved, void* pUserData);

//------------------------------------------------------------------------
// Function:	PLAY_CloseAudioRecord
// Description: Disable audio sampling function
// Parameter:
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_CloseAudioRecord();

//------------------------------------------------------------------------
// Function:	PLAY_SetWaterMarkCallBack
// Description: Set watermark data callback.
// Parameter: nPort,Port number
//		 pFunc,Watermark information to get callback function
//			buf,Watermark data buffer
//			key,Distinguish different watermarks
//			len,Buffer length
//			reallen,Bufffer actual length
//			reserved,®∫y?¶Ã°§??°Ï[0,3],o?®∞?®®???
//				0  I frame data water mark information
//				1  frame water mark
//				2  water mark verification
//				3  intelligent analysis frame
//		 nUser,User defined data
// Returns: BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
typedef int (CALLBACK* GetWaterMarkInfoCallbackFunc)(char* buf, LONG key, LONG len, LONG reallen, LONG type, void* pUserData);
PLAYSDK_API BOOL CALLMETHOD PLAY_SetWaterMarkCallBack(LONG nPort, GetWaterMarkInfoCallbackFunc pFunc, void* pUserData);

//------------------------------------------------------------------------
// Function:	PLAY_CreateFile
// Description: Open file and then automatically allocate channel number
// Parameter:	sFileName,File name, The file size ranges from 4G to 4K
// Returns: BOOL,TRUE--succeeded FALSE--failed
//------------------------------------------------------------------------
PLAYSDK_API DWORD CALLMETHOD PLAY_CreateFile(LPSTR sFileName);

//------------------------------------------------------------------------
// Function:	PLAY_DestroyFile
// Description: Close file and release the automatically allocated channel number
// Parameter: nPort,Port number
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_DestroyFile(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_CreateStream
// Description: Open stream interface and then automatically allocate channel number
// Parameter: nBufPoolSize,Set storage data stream buffer size in the playe
//					The value ranges is
//					[SOURCE_BUF_MIN,SOURCE_BUF_MAX]. Usually it is 900*1024. Please increase the value if the data are not even
// Returns: DWORD,failed Returns false,ReturnsPort number.
//------------------------------------------------------------------------
PLAYSDK_API DWORD CALLMETHOD PLAY_CreateStream(DWORD nBufPoolSize);

//------------------------------------------------------------------------
// Function:	PLAY_DestroyStream
// Description: Close data bit and release the automatically allocated port number
// Parameter: nPort,Port number
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_DestroyStream(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_GetFreePort
// Description: Get free port.
// Parameter:	plPort,Port number.
// Returns:		BOOL,TRUE--succeeded FALSE--failed
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_GetFreePort(LONG *plPort);

//------------------------------------------------------------------------
// Function:	PLAY_ReleasePort
// Description: Release the port got with PLAY_GetFreePort
// Parameter:	nPort,Port number
// Returns:		BOOL,TRUE--succeeded FALSE--failed
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_ReleasePort(LONG lPort);

//------------------------------------------------------------------------
// Function:	PLAY_VerticalSyncEnable
// Description: Vertical synchronize method, support offscreen mode only
//		Called after PLAY_Play. When displaying dynamic images, this method may be useful.

// Parameter: nPort,Port number
//		 bEnable,TRUE Enable vertical synchronize;FALSE Diable vertical synchronize.
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API	BOOL CALLMETHOD PLAY_VerticalSyncEnable(LONG nPort, BOOL bEnable);

//------------------------------------------------------------------------
// Function:	PLAY_GetPicBMP
// Description: Snapshoot. Return BMP picture data buffer.
// Parameter: nPort,Port number
//		 pBmpBuf,Picture buffer. Allocate by user, suggest size:
//			sizeof(BITMAPINFOHEADER) + w * h * 4
//			where w is picture width, h is picture height
//		 dwBufSize,Buffer size
//		 pBmpSize,BMP picture data size
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_GetPicBMP(LONG nPort, PBYTE pBmpBuf, DWORD dwBufSize, DWORD* pBmpSize);

//------------------------------------------------------------------------
// Function: PLAY_GetPicBMPEx
// Description: snapshot BMP image
// Parameter: nPort, channel no.
//		 pBmpBuf, buffer address to store BMP data, allocated by user, must be greater than bmp image size,
//			w and h are image width and height.
//		 dwBufSize, buffer area size
//		 pBmpSize, image size of actual bmp
//		 nWidth,designated bmp width
//		 nHeight, designated bmp height
//		 nRgbType, designated RGB format 0£∫RGB32;1£∫RGB24;
PLAYSDK_API BOOL CALLMETHOD PLAY_GetPicBMPEx(LONG nPort, PBYTE pBmpBuf, DWORD dwBufSize, DWORD* pBmpSize, LONG nWidth, LONG nHeight, int nRgbType);

//------------------------------------------------------------------------
// Function:	PLAY_GetPicJPEG
// Description: Snapshoot. Return JPEG picture data buffer.
// Parameter: nPort,Port number
//		 pJpegBuf,Picture buffer. Allocate by user, suggest size:
//			w * h * 3/2
//			where w is picture width, h is picture height
//		 dwBufSize,Buffer size.
//		 pJpegSize,JPEG picture data size.
//		 quality,Quality of the jpeg compression, value is (0, 100]
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_GetPicJPEG(LONG nPort, PBYTE pJpegBuf, DWORD dwBufSize, DWORD* pJpegSize, int quality);

//------------------------------------------------------------------------
// Function: PLAY_SetVisibleDecodeCallBack
// Description: Decoding call, is same almost with PLAY_SetDecCallBackEx, except that decoding call can
//			display video simultaneously, long-time logic processing is not recommended in call function, in order to avoid delay in display.
// Parameter: nPort, channel no.
//		 cbDec, call function indicator, cannot be NULL, its parameter definitions are as following:
//			nPort, channel no.
//			pFrameDecodeInfo, A/V data after decoding
//			pFrameInfo, image and audio, refer to FRAME_INFO structure
//			pUser, user customized parameter.
//		 pUser, user customized parameter.
PLAYSDK_API BOOL CALLMETHOD PLAY_SetVisibleDecodeCallBack(LONG nPort, fCBDecode cbDec, void* pUser);

//------------------------------------------------------------------------
// Function:	PLAY_RigisterDrawFunEx
// Description: Register one callback function to get current surface device context. You can draw
//		(write) in the DC just as you do in client zone DC of the window. But this DC is not the client
//		zone DC of the window, it is the DC of Off-Screen in DirectDraw. Please note: This interface is
//		null if you use overlay surface. You can draw in the window. It will be displayed if it is not
//		a transparent color.
// Parameter: nPort,Port number
//		 nReginNum,Display zone serial number
//			0~(MAX_DISPLAY_WND-1).
//			If nRegionNum is 0, it means refresh the main display window
//		 DrawFunEx,Callback function handle
//			nPort,Port number
//			hDc,OffScreen, You can operate it just as operate the displayed window DC
//			nUser,User data
//		 nUser,User data
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
typedef void (CALLBACK* fDrawCBFunEx)(LONG nPort,LONG nReginNum,HDC hDc, void* pUserData);
PLAYSDK_API BOOL CALLMETHOD PLAY_RigisterDrawFunEx(LONG nPort, LONG nReginNum, fDrawCBFunEx DrawFunEx, void* pUserData);

//------------------------------------------------------------------------
// Function:	PLAY_CatchResizePic
// Description: Snap. Can set format, height and width.
// Parameter: nPort,Port number
//		 sFileName,file name
//		 lTargetWidth,picture width
//		 lTargetHeight,picture height
//		 ePicfomat,picture type,refer to tPicFomats
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_CatchResizePic(LONG nPort, char* sFileName, LONG lTargetWidth, LONG lTargetHeight, tPicFormats ePicfomat);

//------------------------------------------------------------------------
// Function:	PLAY_GetRealFrameBitRate
// Description: Get video real-time bit rate
// Parameter: nPort,Port number
//		 pBitRate,output Parameter,Returns Video bit rate
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_GetRealFrameBitRate(LONG nPort, double* pBitRate);

//------------------------------------------------------------------------
// Function:	PLAY_StartAVIResizeConvert
// Description: Begin record in AVI mode. Can set video width and height. It is for stream mode only. Call it after PLAY_Play.
// Parameter: nPort,Port number
//		 sFileName,Record file name. Create a folder if there is any file name has no folder.
//		 lWidth,Video format width
//		 lHeight,Video foramt height
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_StartAVIResizeConvert(LONG nPort, char *sFileName, LONG lWidth, LONG lHeight);

//------------------------------------------------------------------------
// Function:	PLAY_StopAVIResizeConvert
// Description: Stop AVI data record. Works with PLAY_StartAVIResizeConvert.
// Parameter: nPort,Port number
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_StopAVIResizeConvert(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_SetFileRefCallBackEx
// Description: Set callback function pointer. Callback when establishing callback. To locate quickly
//		and accurately, system generates a file index when opening a file. This period may take a little
//		bit long. Its speed is about 40M/s, mainly because reading data from the HDD is slow. The index
//		establishment is operated in the background. The functions that need to use this index have to
//		wait until this process ends, while the other interfaces may not be affected
// Parameter: nPort,Port number
//		 pFileRefDoneEx,Callback function pointer
//			nPort,Port number
//			bIndexCreated,Index creation symbol.TRUE=Index creation succeeded. FALSE=Index creation failed.
//			nUser,User data
//		 nUser,User data
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
typedef void (CALLBACK *fpFileRefDoneCBFunEx)(DWORD nPort, BOOL bIndexCreated, void* pUserData);
PLAYSDK_API BOOL CALLMETHOD PLAY_SetFileRefCallBackEx(LONG nPort, fpFileRefDoneCBFunEx pFileRefDoneCBFunEx, void* pUserData);

//------------------------------------------------------------------------
// Function:	PLAY_StartAVIConvert
// Description: Begin AVI conversion and set AVI switch call status.
// Parameter: nPort,Port number
//		 pAVIFunc,Call Function. Parameter definition is shown as below:
//			nPort,Port number
//			lMediaChangeType,AVI_MEDIACHANGE_FRAMERATE means frame change;AVI_MEDIACHANGE_FRAMERATE means resolution change.
//			lUser,Customized Parameter
//			pbIfContinue,TRUE=continue conversion;FALSE=stop conversion
//			sNewFileName,new file name if continue conversion.
//		 lUser,Customized Parameter
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
typedef void (CALLBACK* AVIConvertCallback)(LONG nPort, LONG lMediaChangeType, void* pUserData, BOOL *pbIfContinue, char *sNewFileName);
PLAYSDK_API BOOL CALLMETHOD PLAY_StartAVIConvert(LONG nPort, char *sFileName, AVIConvertCallback pAVIFunc, void* pUserData);

//------------------------------------------------------------------------
// Function:	PLAY_StopAVIConvert
// Description: stop converting avi
// Parameter: nPort,Port number
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_StopAVIConvert(LONG nPort);

//------------------------------------------------------------------------
// Function:	PLAY_SetWaterMarkCallBackEx
// Description: Set watermark data callback.
// Parameter: nPort,Port number
//		 pFunc,Watermark information to get callback function
//			nPort,Port number
//			buf,Watermark data buffer
//			lTimeStamp,Watermark time stamp
//			lInfoType,Distinguish different watermarks,There are three types: WATERMARK_DATA_TEXT,
//				WATERMARK_DATA_JPEG_BMP,WATERMARK_DATA_FRAMEDATA
//		 len,Buffer length
//		 reallen,Bufffer actual length
//		 lCheckResult,1 no error;2 frame water mark;3 frame data error ;4 frame sequence error
//		 nUser,user data
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
typedef int (CALLBACK* GetWaterMarkInfoCallbackFuncEx)(LONG nPort, char* buf, LONG lTimeStamp, LONG lInfoType, LONG len, LONG reallen, LONG lCheckResult, void* pUserData);
PLAYSDK_API BOOL CALLMETHOD PLAY_SetWaterMarkCallBackEx(LONG nPort, GetWaterMarkInfoCallbackFuncEx pFunc, void* pUserData);

//------------------------------------------------------------------------
// Function:	PLAY_SetAudioRecScaling
// Description: Set audio record data zoom rate
// Parameter: fRatio,Zoom rate.from 0 to 1=zoom in audio.1=Original audio.Over 1=audio zoom out.
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_SetAudioRecScaling(float fRatio);

//------------------------------------------------------------------------
// Function:	PLAY_GetAudioRecScaling
// Description: Get audio record data zoom rate
// Parameter: pfRatio,zoom rate. From 0 to 1=Zoom in audio.1=Original audio. Over 1=zoom out audio.
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_GetAudioRecScaling(float* pfRatio);

//------------------------------------------------------------------------
// Function:	PLAY_SetAudioRenderScaling
// Description: Set audio decode zoom rate
// Parameter: nPort,Port number
//		 fRatio,Zoom rate.From 0 to 1=Zoom in audio;1=original audio. Over 1=audio zoom out.
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_SetAudioRenderScaling(LONG nPort, float fRatio);

//------------------------------------------------------------------------
// Function:	PLAY_GetAudioRenderScaling
// Description: Get audio decode zoom rate
// Parameter: nPort,Port number
//		 pfRatio,zoom rate.0 to 1=audio zoom in;1=original audio;over 1=audio zoom out.
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_GetAudioRenderScaling(LONG nPort, float* pfRatio);

//------------------------------------------------------------------------
// Function:	PLAY_SetRotateAngle
// Description: Video
// Parameter: nrotateType,Flip type,Range[0,3]. 0=no flip;1=Rotate by 90 degrees;2=Rotate by 180 degrees;3=Rotate by 270 degrees.
// Returns:		BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_SetRotateAngle(LONG nPort , int nrotateType);

//------------------------------------------------------------------------
// Function: PLAY_SetDelayTime
// Description: Set realplay delay time.
// Parameter: nDelay,Delay time.
//       nThreshold,Threshold time.
// °§¶Ã??: BOOL,TRUE--succeeded FALSE--failed.
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_SetDelayTime(LONG nPort, int nDelay, int nThreshold);

//------------------------------------------------------------------------
// Function:	PLAY_BackOne
// Description: This interface is the same with PLAY_OneByOneBack
// Parameter:
// Returns:
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_BackOne(LONG nPort);

//------------------------------------------------------------------------
// Function: PLAY_SetDecCallBack (PLAY_SetDecodeCallBack is recommended.)
// Description: Set decoding call to replace display in player, controlled by user, the function at//			call before PLAY_Play, when PLAY_Stop, it automatically become invalid. Next time before PLAY_Play,
//			need to set again, decoding part do not control speed, user shall return from call function, decoder
//			decode next data, only for decoding with no display.
// Parameter: nPort, channel no.
//		 DecCBFun, decoding call function indicator, cannot be NULL. Call function parameter definitions are as follows:
//			nPort, channel no.
//			pBuf, A/V data after decoding
//			nSize, pBuf length of A/V data after decoding
//			pFrameInfo, image and audio, refer to FRAME_INFO structure
//			nReserved1, reserved parameter
//			nReserved2, reserved parameter
//------------------------------------------------------------------------
typedef void (CALLBACK* fDecCBFun)(LONG nPort,char * pBuf,LONG nSize,FRAME_INFO * pFrameInfo, void* pUserData, LONG nReserved2);
PLAYSDK_API BOOL CALLMETHOD PLAY_SetDecCallBack(LONG nPort, fDecCBFun DecCBFun);

//------------------------------------------------------------------------
// Function: PLAY_SetDecCallBackEx(PLAY_SetDecodeCallBack is recommended.)
// Description: Set decoding call to replace display in player, controlled by user, the function at
//			call before PLAY_Play, when PLAY_Stop, it automatically become invalid. Next time before PLAY_Play,
//			Need to set again, decoding part do not control speed, user shall return from call function, decoder
//			decode next data, only for decoding with no display.
// Parameter: nPort, channel no.
//		 DecCBFun, decoding call function indicator, cannot be NULL. Call function parameter definitions are as follows:
//			nPort, channel no.
//			pBuf, A/V data after decoding
//			nSize, pBuf length of A/V data after decoding
//			pFrameInfo, image and audio, refer to FRAME_INFO structure
//			nReserved1, reserved parameter
//			nReserved2, reserved parameter
//------------------------------------------------------------------------
PLAYSDK_API BOOL CALLMETHOD PLAY_SetDecCallBackEx(LONG nPort, fDecCBFun DecCBFun, void* pUserData);

//------------------------------------------------------------------------
// Function: PLAY_SetVisibleDecCallBack(PLAY_SetVisibleDecodeCallBack is recommended)
// Description: Decoding call, is same almost with PLAY_SetDecCallBackEx, except that decoding call can
//			display video simultaneously, long-time logic processing is not recommended in call function, in order to avoid delay in display.
// Parameter: nPort, channel no.
//		 DecCBFun, call function indicator, cannot be NULL, its parameter definitions are as following:
//			nPort, channel no.
//			pBuf, A/V data after decoding
//			nSize, pBuf length of A/V data after decoding
//			pFrameInfo, image and audio, refer to FRAME_INFO structure
//			pUserData, user customized parameter
//			nReserved1, reserved parameter
//		 pUserData, user customized parameter.
//------------------------------------------------------------------------
typedef void (CALLBACK* fVisibleDecCBFun)(LONG nPort,char * pBuf,LONG nSize,FRAME_INFO * pFrameInfo, void* pUserData, LONG nReserved1);
PLAYSDK_API BOOL CALLMETHOD PLAY_SetVisibleDecCallBack(LONG nPort, fVisibleDecCBFun DecCBFun, void* pUserData);
#ifdef __cplusplus
}
#endif

#endif``````

whoslooking

IPCT Contributor
The key and the algorithm are more than likely in the uImage file.
That was my thinking too.

montecrypto

IPCT Contributor
Okay gentlemen, Hikvision is still using an XOR-based encoder (technically, a coder-decoder). I have been able to derive the first 1024 bytes of the XOR sequence using well-known cryptanalysis techniques. I performed a frequency count on the sequence to see what kind of distribution we are seeing. Sadly, the algorithm driving this key sequence is much more random than the one used on digicap.dav.
Stay tuned...

That is totally incorrect. Only digicap.dav header is XOR'd in newer firmware. Files inside the dav are encrypted using 3DES-ECB. The keys are in the uImage.

Newer kernels provide /dev/hikded device and IOCTL interfaces used by /bin/ded to encrypt/decrypt files. Still, this does not protect anything from anything. You can still decrypt/repack/encrypt lzma files, update their MD5 checksums stored in new_10.bin and boot any firmware.

josephdex

n3wb
That is totally incorrect. Only digicap.dav header is XOR'd in newer firmware. Files inside the dav are encrypted using 3DES-ECB. The keys are in the uImage.

Newer kernels provide /dev/hikded device and IOCTL interfaces used by /bin/ded to encrypt/decrypt files. Still, this does not protect anything from anything. You can still decrypt/repack/encrypt lzma files, update their MD5 checksums stored in new_10.bin and boot any firmware.
Confirmed.
But don't forget about 'devCfg.bin' )

alastairstevenson

Staff member
And it's little hiding place, holding all the passwords. And the language.

josephdex

n3wb
...Only digicap.dav header is XOR'd in newer firmware
and 'devCfg.bin'

Last edited by a moderator:

alastairstevenson

Staff member
That quote is not from my post - it's from @montecrypto s post.
*edit* Thanks for amending ...

Last edited by a moderator:

wwwoeiq

n3wb
That is totally incorrect. Only digicap.dav header is XOR'd in newer firmware. Files inside the dav are encrypted using 3DES-ECB. The keys are in the uImage.

Newer kernels provide /dev/hikded device and IOCTL interfaces used by /bin/ded to encrypt/decrypt files. Still, this does not protect anything from anything. You can still decrypt/repack/encrypt lzma files, update their MD5 checksums stored in new_10.bin and boot any firmware.
From where /bin/ded is reachable? couldn't execute it on 3.1.9 psh....

Speed666

Getting the hang of it
From nowhere. It is only at boot time and later file is removed, sym link to virtual device too. To get keys you need to decompile kernel (uImage).

alastairstevenson

Staff member
I think @wwwoeiq is referring to an NVR, judging from the firmware rev quoted, where it's always available.

Last edited by a moderator: