Мне нужно проанализировать размер изображения из необработанных данных H.264. Следующий тестовый код работает для случаев, которые я тестирую, но теперь, если происходит сбой на "Z0IAIOKQCgDLYC3AQEBpB4kRUA ==". Результат должен быть 1280x800, но это дает мне 640x1616:
public static void main(String[] args) {
decode(StringUtils.fromBase64("Z0IAKeKQCgDLYC3AQEBpB4kRUA=="));
decode(StringUtils.fromBase64("Z0IAIOKQCgDLYC3AQEBpB4kRUA=="));
decode(StringUtils.fromBase64("Z0IAHuNQFAe2AtwEBAaQeJEV"));
}
static int pos;
static byte[] data;
private static void decode(byte[] data) {
try {
System.out.println();
System.out.println(StringUtils.toHex(data));
System.out.println(StringUtils.toBin(data, 0, data.length, true));
System.out.println();
pos = 0;
T.data = data;
int profile_idc = getU(8);
int constraint_set0_flag = getU(1);
int constraint_set1_flag = getU(1);
int constraint_set2_flag = getU(1);
int constraint_set3_flag = getU(1);
int reserved_zero_4bits = getU(4);
int level_idc = getU(8);
int seq_parameter_set_id = uev();
int log2_max_frame_num_minus4 = uev();
int pict_order_cnt_type = uev();
System.out.println("pict_order_cnt_type=" + pict_order_cnt_type);
if (pict_order_cnt_type == 0) {
uev();
} else if (pict_order_cnt_type == 1) {
getU(1);
sev();
sev();
int n = uev();
System.out.println("n*sev, n=" + n);
for (int i = 0; i < n; i++)
sev();
}
int num_ref_frames = uev();
getU(1);
int pic_width = (uev() + 1) * 16;
int pic_height = (uev() + 1) * 16;
int frame_mbs_only_flag = getU(1);
System.out.println(pic_width + " x " + pic_height);
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
private static int ev(boolean signed) {
int bitcount = 0;
StringBuilder expGolomb = new StringBuilder();
while (getBit() == 0) {
expGolomb.append('0');
bitcount++;
}
expGolomb.append("/1");
int result = 1;
for (int i = 0; i < bitcount; i++) {
int b = getBit();
expGolomb.append(b);
result = result * 2 + b;
}
result--;
if (signed) {
result = (result + 1) / 2 * (result % 2 == 0 ? -1 : 1);
System.out.println("getSe(v) = " + (result) + " " + expGolomb);
} else {
System.out.println("getUe(v) = " + (result) + " " + expGolomb);
}
return result;
}
private static int uev() {
return ev(false);
}
private static int sev() {
return ev(true);
}
private static int getU(int bits) {
int result = 0;
for (int i = 0; i < bits; i++) {
result = result * 2 + getBit();
}
System.out.println("getU(" + bits + ") = " + result);
return result;
}
private static int getBit() {
int mask = 1 << (7 - (pos & 7));
int idx = pos >> 3;
pos++;
return ((data[idx] & mask) == 0) ? 0 : 1;
}
Выход для случая сбоя:
67420020E2900A00CB602DC040406907891150
01100111 01000010 00000000 00100000 11100010 10010000 00001010 00000000 11001011 01100000 00101101 11000000 01000000 01000000 01101001 00000111 10001001 00010001 01010000
getU(8) = 103
getU(1) = 0
getU(1) = 1
getU(1) = 0
getU(1) = 0
getU(4) = 2 << shouldn't this be 0 ? is same with correct parsing!
getU(8) = 0
getUe(v) = 3 00/100
getUe(v) = 13 000/1110 << log2_max_frame_num_minus4 shall be 0-12, inclusive.
getUe(v) = 4 00/101
pict_order_cnt_type=4 << pic_order_cnt_type shall be 0-2, inclusive.
getUe(v) = 3 00/100
getU(1) = 0
getUe(v) = 39 00000/101000
getUe(v) = 100 000000/1100101
getU(1) = 1
640 x 1616