H264 profile-iop explained - h.264

Identify h264 profile and level from profile-level-id in sdp?
How does one identify what the constraints actually mean?
For example I have a profile-type-id: 42801e that translates to:
How am I to relate that to the features defined in the table here?
The above reference identified that the Constraint_set0_flag: 1 means that it's the Constrained Baseline Profile. But how to relate the flag to the three different NO's (from the table) that differentiate the Baseline profile from the Constrained Baseline Profile?
Update
Can't confirm that the above, about identifying the Constrained Baseline profile, is correct. Reference (page 306) for that statement:
Decoders conforming to the Constrained Baseline profile at a
specific level shall be capable of decoding all bitstreams
in which all of the following are true:
– profile_idc is equal to 66 or constraint_set0_flag is equal to 1,
– constraint_set1_flag is equal to 1,
– level_idc and constraint_set3_flag represent a level
less than or equal to the specified level.
It seems only the first condition is fulfilled but the second is false. The parameters for the Baseline profile state
Decoders conforming to the Baseline profile at a specific level shall be capable of decoding all bitstreams in which
profile_idc is equal to 66 or constraint_set0_flag is equal to 1 and in which level_idc and constraint_set3_flag represent a
level less than or equal to the specified level.
and they are both present.

Can you clarify your question? What exactly don't you understand? You have already parsed 42801e as Constrained Baseline Profile Level 3.0.
Constrained Baseline Profile identified by constraint_set0_flag=1 mean that encoded stream don't use any of the features outside of this profile (like FMO or ASO from wikipedia table) and so can be decoded with any decoder with support of Constrained Baseline, Main or High profiles. Streams encoded with Baseline Profile (not Constrained) Profile can use this additional features (or not use but still not be indicated as Constrained) but if they will be used in stream than decoders which support only Constrained Baseline, Main or High profiles wouldn't be able to decode it.
Update
I was wrong. It is Baseline Profile Level 3.0 because constraint_set1_flag=0 and so there is no indication of Constrained Baseline Profile.

Refer to following table from RFC 6184:
Table 5. Combinations of profile_idc and profile-iop
representing the same sub-profile corresponding to the full
set of coding tools supported by one profile. In the
following, x may be either 0 or 1, while the profile names
are indicated as follows. CB: Constrained Baseline profile,
B: Baseline profile, M: Main profile, E: Extended profile,
H: High profile, H10: High 10 profile, H42: High 4:2:2
profile, H44: High 4:4:4 Predictive profile, H10I: High 10
Intra profile, H42I: High 4:2:2 Intra profile, H44I: High
4:4:4 Intra profile, and C44I: CAVLC 4:4:4 Intra profile.
Profile profile_idc profile-iop
(hexadecimal) (binary)
CB 42 (B) x1xx0000
same as: 4D (M) 1xxx0000
same as: 58 (E) 11xx0000
B 42 (B) x0xx0000
same as: 58 (E) 10xx0000
M 4D (M) 0x0x0000
E 58 00xx0000
H 64 00000000
H10 6E 00000000
H42 7A 00000000
H44 F4 00000000
H10I 6E 00010000
H42I 7A 00010000
H44I F4 00010000
C44I 2C 00010000
It is Baseline Profile Level 3.0.

Related

Highest memory transfer

Let's say that a jump instruction is located at memory address 0x20CE88C0. What is the highest (i.e., greatest) 32-bit memory address to which this jump can transfer control?
I know the highest address can be 2^26, but I see others saying 2^28. I don't understand the difference. Why is 2^28?
The J-Type instruction is very simple:
opcode target
6 26 // field size, as bit count
target := instruction[25:0]
JumpAddr := { PC+4[31:28], target, 2'b0 }
PC := JumpAddr
This is the description in the MIPS Green Sheet / Quick Reference Data.  Though a somewhat funny notation (some kind of RTL), it tells us what we need to know about the possible range of jump instructions, by telling us how the processor decodes the J-Type instructions.
What this says is that the current PC+4 provides the upper 4 bits of the new PC address.  Then the address field, sometimes called immediate otherwise called target — either way is 26 bits wide — provides the next 26 bits, and then 00 are the next 2 bits, for a total of 32 bit value for the next PC.
So, with that information, you can compute or form the largest possible address that can be reached from the given PC.  Take PC+4's top 4 bits, and then (string/concatenate onto those 4 bits) a 26 bit max value — its 26 bits unsigned, so 26 all 1's is the max value — then concatenate a 00 (two zero bits) and to make the 32-bit value of the exact address of the maximum addressable location from the j/jal starting at the given PC.

Do the SM's shown in the "occupancy graph" correspond to `blockIdx.x` or register `%smid`?

Do the SM's shown in the "occupancy graph" correspond to blockIdx.x or register %smid?
Here's an example of such a graph
And here's some sample output from when I print the blockIdx.x as the "logical" block, and print register %smid (accessed via assembly) as the physical block.
running on logical Block 77 and Physical SM 75
running on logical Block 31 and Physical SM 62
running on logical Block 37 and Physical SM 74
running on logical Block 74 and Physical SM 69
running on logical Block 66 and Physical SM 53
running on logical Block 45 and Physical SM 11
running on logical Block 43 and Physical SM 7
<snip>
Additionally, I can kind of predict how long each block will take to execute, and blocks ~30 and ~31 aren't predicted to take a long time -- even though they show up as taking a long time on the graph. And some blocks that I "predict" to take a "short amount of time", take longer than a "short time", as shown on the graph. Thus, there seems to be a mismatch between the logical block and duration taken, as shown in the graph.
Finally, given the term "SM" is used in the graph, I would expect the graph to represent the physical SMID, not the logical block number.
Given these three pieces of evidence, I suspect that the number shown in the graph corresponds to the register %smid.
All I'm looking for is confirmation. Once I fully understand the issue, I'll be justified in either better distributing the work across the existing 80 blocks, or just using more blocks to begin with. Thanks!
Quoting Robert Crovella:
The horizontal axis of the graph corresponds to the register %smid. SM
= Streaming Multiprocessor. You could quickly confirm this by running more than 80 blocks and observing that the presented graph does not
proceed beyond 0..79 on the horizontal axis.

Reading / Computing Hex received over RS232

I am using Docklight Scripting to put together a VBScript that communicates with a device via RS232. All the commands are sent in Hex.
When I want to read from the device, I send a 32-bit address, a 16-bit read length, and an 8-bit checksum.
When I want to write to the device, I send a 16-bit data length, the data, followed by an 8-bit checksum.
In Hex, the data that is sent to the device is the following:
AA0001110200060013F81800104D
AA 00 01 11 02 0006 0013F818 0010 4D
(spaced for ease of reading)
AA000111020006 is the protocol header, where:
AA is the Protocol Byte
00 is the Source ID
01 is the Dest ID
11 is the Message Type
02 is the Command Byte
0006 is the Length Byte(s)
The remainder of the string is broken down as follows:
0013F818 is the 32-bit address
0010 is the 16 bit read length
4D is the 8-bit checksum
If the string is not correct, or the checksum is invalid the device replies back with an error string. However, I am not getting an error. The device replies back with the following hex string:
AA0100120200100001000000000100000000000001000029
AA 01 00 12 02 0010 00010000000001000000000000010000 29
(spaced for ease of reading)
Again, the first part of the string (AA00011102) is a part of the protocol header, where:
AA is the Protocol Byte
01 is the Source ID
00 is the Dest ID
12 is the Message Type
02 is the Command Byte
The difference between what is sent to the device, and what the device replies back with is that the length bytes is not a "static" part of the protocol header, and will change based of the request. The remainder of the string is broken down as follows:
0010 is the Length Byte(s)
00010000000001000000000000010000 is the data
29 is the 8-bit Check Sum
The goal is to read a timer that is stored in the NVM. The timer is stored in the upper halves of 60 4-byte NVM words.
The instructions specify that I need to read the first two bytes of each word, and then sum the results.
Verbatim, the instructions say:
Read the NVM elapsed timer. The timer is stored in the upper halves of 60 4-byte words.
Read the first two bytes of each word of the timer. Read the 16 bit values of these locations:
13F800H, 13F804H, 13808H, and continue to 13F8ECH.
Sum the results. Multiply the sum by 409.6 seconds, then divide by 3600 to get the results in hours.
My knowledge of bits, and bytes, and all other things is a bit cloudy. The first thing I need to confirm is that I am understanding the read protocol correctly.
I am assuming that when I specify 0010 as the 16 bit read length, that translates to the 16-bit values that the instructions want me to read.
The second thing I need to understand a little better is that when it tells me to read the first two bytes of each word, what exactly constitutes the first two bytes of each word?
I think what confuses me a little more is that the instructions say the timer is stored in the upper half of the 4 byte word (which to me seems like the first half).
I've sat with another colleague of mine for a day trying to figure out how to make this all work, and we haven't had any consistent results with our trials.
I have looked on the internet to find something that would explain this better in the context being used.
Another worry is that the technical data I am using to accomplish this project isn't 100% accurate in their instructions, and they have conflicting information or skipping information throughout their publication (which is probably close to 1000 pages long).
What I would really appreciate is someone who has a much better understanding of hex / binary to review the instructions I've posted, and provide some feedback on my interpretation of the instructions provided, and provide any information.

http/2 dynamic table size update clarification

In the http/2 protocol we see the following statement for dynamic table size update:
SETTINGS_HEADER_TABLE_SIZE (0x1): Allows the sender to inform the
remote endpoint of the maximum size of the header compression
table used to decode header blocks, in octets. The encoder can
select any size equal to or less than this value by using
signaling specific to the header compression format inside a
header block (see [COMPRESSION]). The initial value is 4,096
octets.
The initial size for both encoder and decoder is 4096 bytes according to RFC.
In SETTINGS frame in wireshark, i can see the new table size passed to the ENDPOINT ( google.com in this case )
0000 00 00 12 04 00 00 00 00 00 **00 01 00 01 00** 00 00
0010 04 00 02 00 00 00 05 00 00 40 00
00 01 00 01 00 is a pattern for SETTINGS_HEADER_TABLE_SIZE = 65536
What i can't understand does it actually tells the endpoint that the dynamic table used to decode the headers from this ENDPOINT inside browser is 65536 bytes long, or does it tell the ENDPOINT that ENDPOINT dynamic table size should be 65536 ?
And reversed, i assume that the ENDPOINT must sent SETTINGS_HEADER_TABLE_SIZE to tell the browser its dynamic table used for decoding the headers from ENDPOINT but i don't see that option sent back by the ENDPOINT. Can someone explain this?
Also there is a signal for dynamic table size update, mentioned in RFC, which is sent inside the HEADERS frame.
A dynamic table size update starts with the '001' 3-bit pattern,
followed by the new maximum size, represented as an integer with a
5-bit prefix (see Section 5.1).
The new maximum size MUST be lower than or equal to the limit
determined by the protocol using HPACK. A value that exceeds this
limit MUST be treated as a decoding error. In HTTP/2, this limit is
the last value of the SETTINGS_HEADER_TABLE_SIZE parameter (see
Section 6.5.2 of [HTTP2]) received from the decoder and acknowledged
by the encoder (see Section 6.5.3 of [HTTP2]).
There is this line received from the decoder and acknowledged by the encoder, so does this signal is sent to limit the encoding dynamic table size ? I comletely lost, and it is not obvious from wireshark captures how this is handled correctly
UPDATE
Ok, i looked more on the logs of wireshark from firefox on the site of walmart.com ( since there is a lot of headers involved). Sometimes firefox sends the dynamic table size update signal in the headers frame, with the size smaller then the initial SETTINGS_HEADER_TABLE_SIZE sent by firefox on the beginning of connection. I wrote a firefox dynamic table on a paper and shrink it as if i expected the dynamic table size update would do. Turns out that shrinking it to smaller size produce incorrect headers.. So apparently the dynamic table size update affect only remote endpoint.. ( well i guess it is ). I also looked up on nigthttp and a c# implementation, and there they actually shrink the encoder table size, while sending dynamic table size update signal. I get a feeling that everyone have a complete different implementation for this protocol.. it's a complete nightmare to understand.
As you figured out there are multiple things which indicate the table size:
The maximum table size setting (as indicated in a HTTP/2 SETTINGS frame)
The actual used table size - which is encoded in a HEADERS frame in HPACK format
If we only look at the headers which are flowing from the client (browser) to a server we will see the following things going on:
As long as nobody has an information from the remote side the default values are used, which means the client expects that the server supports a maximum table size of 4kB (SETTINGS_HEADER_TABLE_SIZE) and it also uses this size as the initial table size.
The server can optionally inform the client through the HTTP/2 SETTINGS frame that it only supports smaller header tables. This information is contained in the SETTINGS_HEADER_TABLE_SIZE field, a SETTINGS frame which is sent from the server to the client.
The client can adjust the actually used [dynamic] header table size through the Dynamic Table Size Update in a HEADERS frame. This will always indicate the table size that is actually used on the encoder side - and which therefore also must be set on decoder side to be able to retrieve the same data. The sending side is free to set the actual used table size to anything between 0 and the maximum size that is supported by the remote side (in SETTINGS_HEADER_TABLE_SIZE). A typical strategy for implementations is to to always shrink the used table size when it's currently larger than what the remote supports. And to increase the table size when the remote supports bigger tables and the implementation also still can go bigger. There might be some race conditions where one end already set and used a larger table size than what the remote side actually supports, e.g. because the SETTINGS frame which indicates the lower limit was not received before a client encoded the first pair of headers. In that case the remote side might detect the use of a too big table size and reset the connection. To avoid this situations both sides of the connection should in reality at least support the default table size of 4kB, and ideally only increase the limit dynamically and never shrink it.
Now I mentioned that one pair of max. table size settings and actual table size settings is used for transmitting HEADERS from one end of the connection (client) to the other (server). But in total there is also a second pair of both, for the headers which are sent from the server to the client. For this case the client/browser also indicates in a SETTINGS frame how big the max. header table is that it supports and the server sends the size of the actual header table that is used.

In-memory layout of array in Turbo Pascal

We have an old application in Turbo Pascal which can save its internal state into a file, and we need to be able to read/write this file in a C# application.
The old application generates the file by dumping various in-memory data structures. In one place, the application just dumps a range of memory, and this memory range contains some arrays. I am trying to noodle out the purpose of the bytes immediately preceding the actual array elements. In particular, the first two items in the block can be represented as:
type
string2 = string[2];
stringarr2 = array[0..64] of string2;
string4 = string[4];
stringarr4 = array[0..64] of string4;
In the data file, I see the following byte sequence:
25 00 02 02 41 42 02 43 44 ...
The 25 is the number of elements in the array. The 02 41 42 is the first string element, "AB"; the 02 43 44 is the second string element, "CD", and so on. I don't know what the 00 02 between the array element count and the first array element refers to. It's possible the array element count is 25 00 and the element size is 02, but each array element is actually 3 bytes in size.
In the place in the file where the array of 4-character strings starts, I see the following:
25 00 04 00 00 04 41 42 43 44 04 45 46 47 48
Again, there's the 25 which is the number of elements in the array; 04 41 42 43 44 is the first element in the array, "ABCD", and so on. In between there are the bytes 00 04 00 00. Maybe they are flags. Maybe they are some kind of indication of the shape of the array (but I don't see how 02 and 04 both indicate a one-dimensional array).
I don't have access to Turbo Pascal to try writing different kinds of arrays to a file, and don't have authorization to install something like Free Pascal, so my opportunities for experimentation along those lines are very limited.
These arrays are not dynamic, since Turbo Pascal didn't have them.
Thanks in advance for any dusty memories.
Pascal arrays have no bookkeeping data. You have an array of five-byte data structures (string[4]), so an array of 65 of them occupies 65*5=325 bytes. If the program wrote more than that, then it's because the program took special measures to write more. The "extra" values weren't just sitting in memory that the program happened to write to disk when it naively wrote the whole data structure with SizeOf. Thus, the only way to know what those bytes mean is to find the source code or the documentation. Merely knowing that it's Turbo Pascal is no help.
It's possible that the first section of the file is intentionally the same size as all the other array elements. For the two-character strings, the "header" is three bytes, and for the four-character strings, the "header" is five bytes, the same as the size of the strings. That would have allowed the program to use a file of string4 data type for the file, and then just skip the file's first record. The zero between the file length and the string length in the header might belong to either of those fields, and the remaining two zero bytes might just be filler.
Besides the layout of the individual strings of characters in the file, you will also need to consider what code page those single-byte characters are from. C# chars are unicode 2 byte chars.
If you're lucky, the original file data contains only ASCII 7 bit characters, which covers characters of the English alphabet. If the original data contains "European" letters such as umlauts or accented characters, these will be "high ascii" char values in the range 128..255. You'll need to perform an encoding conversion to see these characters correctly in C#. Code page 1252 Windows Latin 1 would be a good starting point.
If the original file data contains Japanese, Chinese, Korean, Thai, or characters from other "Eastern" scripts, you have a lot of work ahead of you.
Turbo Pascal strings are prefixed with a length byte. So a string[2] is actually 3 bytes: length, char1 and char2. An array of string[2] will hold all the strings one by one directly after each other in memory. If you do a blockwrite with the array as a parameter it will immediately start with the first string, it will not write any headers etc. So if you have the source you should be able to see what it writes before the array.