Created
August 7, 2012 06:23
-
-
Save dongri/3282339 to your computer and use it in GitHub Desktop.
H.264
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#define bool unsigned int | |
#define true 1 | |
#define false 0 | |
int profile = 0; | |
int level = 0; | |
int width = 0; | |
int height = 0; | |
int pos; | |
char data[8]; | |
int getNextBit(){ | |
int mask = 1 << (7 - (pos & 7)); | |
int index = pos >> 3; | |
pos++; | |
return ((data[index] & mask) == 0) ? 0 : 1; | |
} | |
int ev(bool flag) { | |
int bitcount = 0; | |
while (getNextBit() == 0) { | |
bitcount++; | |
} | |
int result = 1; | |
int i = 0; | |
for (i = 0; i < bitcount; i++) { | |
int b = getNextBit(); | |
result = result * 2 + b; | |
} | |
result--; | |
if (flag) { | |
result = (result + 1) / 2 * (result % 2 == 0 ? -1 : 1); | |
} | |
return result; | |
} | |
int uev() { | |
return ev(false); | |
} | |
int sev() { | |
return ev(true); | |
} | |
int getU(int bits) { | |
int result = 0; | |
int i; | |
for (i = 0; i < bits; i++) { | |
result = result * 2 + getNextBit(); | |
} | |
//printf("getU(%d) = %d\n" ,bits, result); | |
return result; | |
} | |
void parse() { | |
pos = 0; | |
int profile_idc = getU(8); | |
profile = profile_idc; | |
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); | |
level = level_idc; | |
int seq_parameter_set_id = uev(); | |
int log2_max_frame_num_minus4 = uev(); | |
int pict_order_cnt_type = uev(); | |
int log2_max_pic_order_cnt_lab_minus4; | |
int delta_pic_order_always_zero_flag; | |
int offset_for_non_ref_pic; | |
int offset_for_top_to_bttom_field; | |
if (pict_order_cnt_type == 0) { | |
log2_max_pic_order_cnt_lab_minus4 = uev(); | |
} else if (pict_order_cnt_type == 1) { | |
delta_pic_order_always_zero_flag = getU(1); | |
offset_for_non_ref_pic = sev(); | |
offset_for_top_to_bttom_field = sev(); | |
int n = uev(); | |
int i = 0; | |
for (i = 0; i < n; i++){ | |
sev(); | |
} | |
} | |
int num_ref_frames = uev(); | |
int gaps_in_frame_num_value_allowed_flag = getU(1); | |
int pic_width_in_mbs_minus1 = uev(); | |
int pic_height_in_mbs_minus1 = uev(); | |
int pic_width = (pic_width_in_mbs_minus1 + 1) * 16; | |
int pic_height = (pic_height_in_mbs_minus1 + 1) * 16; | |
int frame_mbs_only_flag = getU(1); | |
width = pic_width; | |
height = pic_height; | |
//Debug | |
printf("\n"); | |
printf("profile_idc = %d\n", profile_idc); | |
printf("constraint_set0_flag = %d\n", constraint_set0_flag); | |
printf("constraint_set1_flag = %d\n", constraint_set1_flag); | |
printf("constraint_set2_flag = %d\n", constraint_set2_flag); | |
printf("constraint_set3_flag = %d\n", constraint_set3_flag); | |
printf("reserved_zero_4bits = %d\n", reserved_zero_4bits); | |
printf("level_idc = %d\n", level_idc); | |
printf("seq_parameter_set_id = %d\n", seq_parameter_set_id); | |
printf("log2_max_frame_num_minus4 = %d\n", log2_max_frame_num_minus4); | |
printf("pict_order_cnt_type = %d\n" , pict_order_cnt_type); | |
printf("log2_max_pic_order_cnt_lab_minus4 = %d\n", log2_max_pic_order_cnt_lab_minus4); | |
printf("delta_pic_order_always_zero_flag = %d\n", delta_pic_order_always_zero_flag); | |
printf("offset_for_non_ref_pic = %d\n", offset_for_non_ref_pic); | |
printf("offset_for_top_to_bttom_field = %d\n", offset_for_top_to_bttom_field); | |
printf("num_ref_frames = %d\n", num_ref_frames); | |
printf("gaps_in_frame_num_value_allowed_flag = %d\n", gaps_in_frame_num_value_allowed_flag); | |
printf("pic_width_in_mbs_minus1 = %d\n", pic_width_in_mbs_minus1); | |
printf("pic_height_in_mbs_minus1 = %d\n", pic_height_in_mbs_minus1); | |
printf("frame_mbs_only_flag = %d\n", frame_mbs_only_flag); | |
} | |
const int BitSize = sizeof(int) * 2; | |
void dtob(int x) { | |
int bit = 1, i; | |
char c[BitSize]; | |
for (i = 0; i < BitSize; i++) { | |
if (x & bit) | |
c[i] = '1'; | |
else | |
c[i] = '0'; | |
bit <<= 1; | |
} | |
printf(" : "); | |
for ( i = BitSize - 1; i >= 0; i-- ) { | |
putchar(c[i]); | |
} | |
printf("\n"); | |
} | |
int main(void){ | |
FILE *fp; | |
int c; | |
int prev1=0; | |
int prev2=0; | |
int prev3=0; | |
int count = 0; | |
bool isStart = false; | |
bool isSPS = false; | |
bool isPPS = false; | |
if ((fp = fopen( "es.264", "r")) == NULL) { | |
fprintf(stderr, "Can't Open File\n"); | |
exit(-1); | |
} | |
printf("\n=============Debug==============\n"); | |
while ((c = fgetc(fp)) != EOF){ | |
if (isSPS == true){ | |
count++; | |
printf("0x%02x ", c); | |
data[count-1] = c; | |
dtob(c); | |
} | |
if (isPPS == true){ | |
printf("0x%02x ", c); | |
dtob(c); | |
} | |
if (isStart == true){ | |
if (7 == (c & 0x1F)){ | |
printf("SPS\n"); | |
isSPS = true; | |
} | |
if (8 == (c & 0x1F)){ | |
printf("PPS\n"); | |
isPPS = true; | |
} | |
isStart = false; | |
} | |
if (prev1 == 0x00 && prev2 == 0x00 && prev3 == 0x00 && c == 0x01){ | |
isStart = true; | |
isSPS = false; | |
isPPS = false; | |
} | |
prev3 = prev2; | |
prev2 = prev1; | |
prev1 = c; | |
} | |
fclose(fp); | |
parse(); | |
printf("\n=============Answer==============\n"); | |
printf("\n"); | |
printf("Width x Height = %d x %d\n", width, height); | |
printf("Profile = %d\n", profile); | |
printf("Level = %d\n", level); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment