I am trying to parse an SPS inside an avcC box in a MP4 file. For some reason, I don't get the expected timing values while everything else is fine. Using a hex editor, I extracted these bytes to works with.
byte[] spsSmall =
{
0x67, 0x42, 0xC0, 0x1E, 0x9E, 0x21, 0x81, 0x18, 0x53, 0x4D, 0x40, 0x40,
0x40, 0x50, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x03, 0xC8,
0xF1, 0x62, 0xEE
};
And this is H264 Analyzer report after converting my clip .mp4 to .h264
Nal length 29 start code 4 bytes
ref 3 type 7 Sequence parameter set
profile: 66
constaint_set0_flag: 1
constaint_set1_flag: 1
constaint_set2_flag: 0
constaint_set3_flag: 0
level_idc: 30
seq parameter set id: 0
log2_max_frame_num_minus4: 6
pic_order_cnt_type: 0
log2_max_pic_order_cnt_lsb_minus4: 7
num_ref_frames: 2
gaps_in_frame_num_value_allowed_flag: 0
pic_width_in_mbs_minus1: 34 (560)
pic_height_in_map_minus1: 19
frame_mbs_only_flag: 1
derived height: 320
direct_8x8_inference_flag: 1
frame_cropping_flag: 0
vui_parameters_present_flag: 1
aspect_ratio_info_present_flag: 0
overscan_info_present_flag: 0
video_signal_info_present_flag: 1
video_format: 5
video_full_range_flag: 0
colour_description_present_flag: 1
colour_primaries: 1
transfer_characteristics: 1
matrix_coefficients: 1
chroma_loc_info_present_flag: 0
timing_info_present_flag: 1
num_units_in_tick: 1
time_scale: 60
fixed_frame_scale: 1
nal_hrd_parameters_present_flag: 0
vcl_hrd_parameters_present_flag: 0
pic_struct_present_flag: 0
motion_vectors_over_pic_boundaries_flag: 1
max_bytes_per_pic_denom: 0
max_bits_per_mb_denom: 0
log2_max_mv_length_horizontal: 10
log2_max_mv_length_vertical: 10
num_reorder_frames: 0
max_dec_frame_buffering: 2
So I should expect num_units_in_tick to be 1 and time_scale to be 60 but I get for some reason a num_units_in_tick of 48 and a time_scale of 16777216.
You can find my implementation here
I checked FFmpeg and others implementations to see if I was missing something, but they seem to do the same things as me. I tried other clips, but I still have everything right other than the timing info. The doc don't seem to provide more than what I already know. Not only that, I have the colour_primaries, transfer_characteristics, matrix_coefficients all equals to 1 right before the timing info. If I was too far or too early, I would get the value wrong. The chance I get 24 bits with this exact sequence are really low. So I am lost to what I should do.
I found this post saying
If you are using field-based video then this will be a field rate, so
you'll have to halve it to get a frame rate.
Not sure what it meant. Even if I halve the number of bits (32 ⇾ 16) or divide by 2, I don't get something close to this.
You should remove emulation_prevention_three_byte from the NAL i.e. you should search for 0x00, 0x00, 0x03 byte aligned sequences and remove 0x03 from there. So that resulting unescaped spsSmall would be:
byte[] spsSmall =
{
0x67, 0x42, 0xC0, 0x1E, 0x9E, 0x21, 0x81, 0x18, 0x53, 0x4D, 0x40, 0x40,
0x40, 0x50, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0xC8, 0xF1, 0x62,
0xEE
};
Related
I'm using PCSC-Sharp to transmit commands to a card. The specific command is:
00 A4 04 0C 0C D2 76 00 01 35 4B 41 4E 4D 30 31 00 00
So I did the following:
var contextFactory = ContextFactory.Instance;
using (var ctx = contextFactory.Establish(SCardScope.System)) {
using (var isoReader = new IsoReader(ctx, readerName, SCardShareMode.Shared, SCardProtocol.Any, false)) {
var apdu = new CommandApdu(IsoCase.Case4Short, isoReader.ActiveProtocol) {
CLA = 0x00,
Instruction = InstructionCode.SelectFile, //0xA4
P1 = 0x04,
P2 = 0x0C,
Data = new byte[] { 0x0C, 0xD2, 0x76, 0x00, 0x01, 0x35,
0x4B, 0x41, 0x4E, 0x4D, 0x30, 0x31, 0x00, 0x00 },
Le = 0x00,
};
var response = isoReader.Transmit(apdu);
Console.WriteLine("SW1 SW2 = {0:X2} {1:X2}", response.SW1, response.SW2);
}
}
But on Transmit an InvalidApduException is thrown on getting SW1.
Am I missing something when converting the command string into a CommandApdu instance?
Mifare cards have no file system (just some numbered sectors) and understand no ISO 7816-4 APDUs, so InvalidApduException seems correct. The readers, which are able to handle MIFARE typically understand some pseudo-APDUs (CLA=0xFF, ...) which are translated accordingly. While these depend on the respective reader, some pretty established conventions exist, which you should find easily here using the mifare tag.
The SELECT by AID (for file-system based cards) or SELECT application (for Javacards) you are attempting is unlikely to have such a direct translation, since MIFARE cards have no similar concept.
I have an encryption algorithm (RSA) and trying to make it able to encrypt and decrypt text of any length, the problem I faced is somewhy after encryption of block of bytes, if I convert is to string (using Encoding.ASCII.GetString) and then go back (with GetBytes) - I don't get the same array of bytes, same with UTF8, I'm not really into encodings, can someone help how can I solve this problem, so I can convert encrypted bytes into string and pass it to decryption algorithm and it will get proper bytes?
byte[] bytes = new byte[] { 0xe1, 0xde, 0x4a, 0x10, 0xea, 0x74, 0x8f, 0x18, 0xd7, 0x93, 0x04, 0x7a, 0x10, 0xb2, 0xa8, 0xfa, 0x11, 0x00, 0x7a, 0xfb, 0xcb,
0x19, 0xb7, 0xf5, 0x25, 0x26, 0x6d, 0xa0, 0x0d, 0xdc, 0xe5, 0x0a };
Console.WriteLine(string.Join(" ", bytes));
// 255 222 74 16 234 116 143 24 215 147 4 122 16 178 168 250 17 0 122 251 203 25 183 245 37 38 109 160 13 220 229 10
byte[] bytes2 = Encoding.ASCII.GetBytes(Encoding.ASCII.GetString(bytes));
Console.WriteLine(string.Join(" ", bytes2));
// 63 63 74 16 63 116 63 24 63 4 122 16 63 63 63 17 0 122 63 63 25 63 63 37 38 109 63 13 63 63 10
byte[] bytes3 = Encoding.UTF8.GetBytes(Encoding.ASCII.GetString(bytes));
Console.WriteLine(string.Join(" ", bytes3));
// 63 63 74 16 63 116 63 24 63 4 122 16 63 63 63 17 0 122 63 63 25 63 63 37 38 109 63 13 63 63 10
Array bytes I got from encrypting "hello world!" with 32 bytes key from my encryption algorithm, as you see, ascii nor utf8 to string and then back to bytes doesn't gives me back my original array of bytes somewhy
You're not supposed to use the Encoding.XYZ objects for converting sequences of bytes into strings unless those bytes actually make up a string in that encoding. Their purpose is to do the bytes-to-string conversion when you're reading text from any form of medium that serves bytes, such as FileStream or similar. However, those bytes actually have to be correctly encoded for the encoding you choose. You cannot convert arbitrary sequences of bytes to strings using these encodings. As you've already observed, they will mangle the result. You might get lucky for quite a few byte sequences, but if you're using any of the cryptographic secure encryption algorithms, that luck will run out immediately.
Instead, use something like Base64 or 85. Base64 is built into .NET, and if you have this code:
byte[] original = ...
string encoded = Encoding.ASCII.GetString(original);
byte[] decoded = Encoding.ASCII.GetBytes(encoded);
all you have to do is change to this:
byte[] original = ...
string encoded = Convert.ToBase64String(original);
byte[] decoded = Convert.FromBase64String(encoded);
MS provided samples to send and receive Bluetooth Low Energy advertisements.
I saw this very helpful answer for breaking down the iBeacon packet. There's also an example for setting BluetoothLEAdvertisement.ManufacturerData as the ibeacon standards.
May I ask how can I set the Flags of the BluetoothLEAdvertisement?
For example set the value to:
02-01-06
Thanks
Edit 1:
Here's the code:
using System;
using System.Management;
using System.Text.RegularExpressions;
using Windows.Devices.Bluetooth.Advertisement;
using System.Runtime.InteropServices.WindowsRuntime;
namespace BLE_iBeacon
{
class IBeacon
{
static void Main()
{
Console.WriteLine("Advertising as iBeacon. Press Enter to exit");
// Create and initialize a new publisher instance.
BluetoothLEAdvertisementPublisher publisher = new BluetoothLEAdvertisementPublisher();
// Add a manufacturer-specific section:
var manufacturerData = new BluetoothLEManufacturerData();
// Set the company ID for the manufacturer data.
// 0x004C Apple, Inc.
manufacturerData.CompanyId = 0x004C;
byte[] dataArray = new byte[] {
// last 2 bytes of Apple's iBeacon
0x02, 0x15,
// UUID E4 C8 A4 FC F6 8B 47 0D 95 9F 29 38 2A F7 2C E7
0xE4, 0xC8, 0xA4, 0xFC,
0xF6, 0x8B, 0x47, 0x0D,
0x95, 0x9F, 0x29, 0x38,
0x2A, 0xF7, 0x2C, 0xE7,
// Major
0x00, 0x00,
// Minor
0x00, 0x01,
// TX power
0xC5
};
manufacturerData.Data = dataArray.AsBuffer();
// Add the manufacturer data to the advertisement publisher:
publisher.Advertisement.ManufacturerData.Add(manufacturerData);
publisher.Advertisement.Flags = BluetoothLEAdvertisementFlags.GeneralDiscoverableMode;
publisher.Start();
Console.Read();
publisher.Stop();
}
}
}
Edit 2:
In the C# code if I do not set the Flags, my windows laptop would advertise raw packet like:
04 3E 27 02 01
02 01 0D 45 84 D3 68 21 1B 1A FF 4C 00
02 15 E4 C8 A4 FC F6 8B 47 0D 95 9F 29 38 2A F7 2C E7
00 00 00 01 C5 BA
My purpose is to use raspberry pi's as BLE receivers. I used the Radius Networks's code here. You can see in the ibeacon_scan script, they check the packet of the advertisement to see if it's an iBeacon by:
if [[ $packet =~ ^04\ 3E\ 2A\ 02\ 01\ .{26}\ 02\ 01\ .{14}\ 02\ 15 ]]; then
So the previous raw packet would not be recognized, for missing the flag part. I am wondering if I can advertise the packet with the Flags, like:
04 3E 2A 02 01
02 01 0D 45 84 D3 68 21 1B **02 01 1A** 1A FF 4C 00
02 15 E4 C8 A4 FC F6 8B 47 0D 95 9F 29 38 2A F7 2C E7
00 00 00 01 C5 BA
instead of changing the scan script in the pi.
iBeacon on Windows
The following code publishes an iBeacon on Windows 10 machines:
// Create and initialize a new publisher instance.
BluetoothLEAdvertisementPublisher publisher = new BluetoothLEAdvertisementPublisher();
// Add a manufacturer-specific section:
var manufacturerData = new BluetoothLEManufacturerData();
// Set the company ID for the manufacturer data.
// 0x004C Apple, Inc.
manufacturerData.CompanyId = 0x004c;
// Create the payload
var writer = new DataWriter();
byte[] dataArray = new byte[] {
// last 2 bytes of Apple's iBeacon
0x02, 0x15,
// UUID e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0
0xe2, 0xc5, 0x6d, 0xb5,
0xdf, 0xfb, 0x48, 0xd2,
0xb0, 0x60, 0xd0, 0xf5,
0xa7, 0x10, 0x96, 0xe0,
// Major
0x00, 0x00,
// Minor
0x00, 0x01,
// TX power
0xc5
};
writer.WriteBytes(dataArray);
manufacturerData.Data = writer.DetachBuffer();
// Add the manufacturer data to the advertisement publisher:
publisher.Advertisement.ManufacturerData.Add(manufacturerData);
publisher.Start();
Proximity UUID
While testing this out, my iOS device would not recognize the Proximity UUID you provided. I'm guessing this is because you generated it yourself, so the app doesn't know what to look for. Instead, I used the proximity UUID from this answer which identifies the Windows 10 device as an AirLocate iBeacon.
Flags
Windows 10 does not currently allow developers to set the flags for a Bluetooth LE advertisement. Luckily, for the Windows device to be recognized as an iBeacon, you don't need those flags!
Ideally, you want to set the flags byte to 0x1a, but other values may still work. The important flag to set is General Discoverable (0x02).
You can use BluetoothLEAdvertisementFlags is an enumeration of bit values here.
My C# is very rusty, but you might try setting the flags hex value directly with: publisher.Advertisement.Flags = 0x1A;
I have a .sol file and I want to edit it but I've noticed that the numbers work like this
0x3F, 0xF0 = 1
0x40, 0x00 = 2
0x40, 0x08 = 3
0x40, 0x10 = 4
0x40, 0x14 = 5
0x40, 0x18 = 6
0x40, 0x1C = 7
0x40, 0x20 = 8
0x40, 0x22 = 9
0x40, 0x24 = 10
0x40, 0x26 = 11
0x40, 0x28 = 12
0x40, 0x2A = 13
0x40, 0x2E = 15
0x40, 0x30 = 16
0x40, 0x31 = 17
0x40, 0x32 = 18
0x40, 0x33 = 19
0x40, 0x34 = 20
I don't want to have a giant table and it might change once it gets to about 500 so I'd rather want to know how to calculate the number its self from the hex. Anyone got any ideas?
-I'm using this for a gamesave editor so I can't just use a sol editor, I need to know how it's done.
-For future people who may come across this post in hope of accomplishing what I tried to do, I decided it was too much of a problem to get the IEEE754 hex format which I'd required, so I ended up making a scraper which did it for me, the numbers go up to 1024. Just add this into a long array http://pastebin.com/9EeYcWq2
I'm using C# to write the following binary value to the system registry:
byte[] valueToSet = { 84, 01, 00, 00 };
Registry.SetValue(keyName, "00036601", valueToSet);
// returns void as expected.
When I view the written value using regedit, I see the displayed value as 54 01 00 00. This is incorrect
Conversely when I set the value to 84,01,00,00 manually in the registry, and run this code
object ttt = Registry.GetValue(keyName, "00036601", null);
// returns 132, 1, 0, 0
Is this an Endian issue? What is the correct way to fix this?
It's a hexadecimal issue. RegEdit displays values in hexadecimal, and you're working with decimal in C#.
The two values are equivalent:
0x54 == 84
The registry editor displays the value in hexadecimal. The decimal value 84 is equal to the hexadecimal value 0x54, and hexadecimal 0x84 is equal to decimal 132.
I think you are trying to specify the literals in hex. However, without the 0x hex-prefix, the compiler interprets them as decimals.
Try this instead:
byte[] valueToSet = { 0x84, 0x01, 0x00, 0x00 };
The values shown in the registry for binary types are in hexidecimal notation. Decimal 84 == hex 0x54.
interesting thing to note is that 84 (decimal) == 54 (hex)