Skip to content

Instantly share code, notes, and snippets.

@dongri
Created August 7, 2012 06:23
Show Gist options
  • Save dongri/3282339 to your computer and use it in GitHub Desktop.
Save dongri/3282339 to your computer and use it in GitHub Desktop.
H.264
#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