If you're interested in rate control, then you need to know the size of each picture in a H.264 bitstream. Here's some C code to get you started.
Code:
/*
H.264 picture size parser
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/file.h>
#define TRUE 1
#define FALSE 0
int main(int argc, char **argv)
{
FILE *fp;
static unsigned char buffer[16384];
int i, length;
static int first = TRUE;
static unsigned int parse = 0;
unsigned int picture_size = 0;
if (argc != 2) {
fprintf(stderr, "usage: bits <infile>\n");
exit(-1);
}
/*--- open binary file (for parsing) ---*/
fp = fopen(argv[1], "rb");
if (fp == 0) {
fprintf(stderr, "Cannot open bitstream file <%s>\n", argv[1]);
exit(-1);
}
while(!feof(fp)) {
length = fread(&buffer[0], 1, 16384, fp);
for(i = 0; i < length; i++) {
parse = (parse << 8) + buffer[i];
if ((parse & 0xffffff00) == 0x00000100) { /* look for a start code */
if ((parse & 0xffffff9f) == 0x00000101 || (parse & 0xffffff9f) == 0x00000105) { /* look for a coded slice */
i++;
picture_size++;
parse = (parse << 8) + buffer[i];
if (parse & 0x00000080) { /* make sure it's the first slice of a picture */
if (first == TRUE) {
first = FALSE;
picture_size = 0;
}
else {
printf("%8d\n", picture_size * 8);
picture_size = 0;
}
}
}
}
picture_size++;
}
}
fclose(fp);
return 0;
}
Once you know the size of each picture, it's easy to calculate the VBV occupancy.
1) Initialize the size of the VBV buffer (in bits). Either to full or some percentage of full.
2) Subtract the size of a picture (in bits) from the VBV. Check to see if the VBV buffer fullness is zero or less than zero. If zero or less than zero, it's a VBV underflow.
3) Add the number of bits based on the VBV rate. For example, if the vbv-maxrate is 10,000,000 bits/second and the frame rate is 25 frames/second, then add 400,000 bits. If the stream is really CBR (in x264, you need to explicitly turn on picture stuffing), then you should not exceed the size of the VBV buffer. If you exceed the size of the VBV buffer, it's a VBV overflow. For VBR streams (or CBR stream without picture stuffing), there is no VBV overflow and you just set the VBV level back to full on an overflow.
4) Repeat steps 2 and 3 for the entire bitstream. Note that the number of bits to add on step 3 is based on frame rate. Therefore, VBV doesn't apply to variable frame rate and telecine flags need to be accounted for. Also, if the frame rate is not an integer (like 29.97 fps), then be sure to use floating point math and add fractional bits back to the VBV.
Ron