/* The code refers to
 * http://keyj.s2000.at/files/projects/h264-src.tar.gz
 */
#include <string.h>
#include <stdio.h>

#define SLICE_NUM 4 
#define NAL_BUF_SIZE  65536  // maximum NAL unit size
#define RING_BUF_SIZE  8192  // input ring buffer size, MUST be a power of two!

typedef struct _nal_unit {
  int NumBytesInNALunit;
  int forbidden_zero_bit;
  int nal_ref_idc;
  int nal_unit_type;
  unsigned char *last_rbsp_byte;
} nal_unit;
 typedef struct _slice_header {
  int first_mb_in_slice;
} slice_header;
 
static int get_next_nal_unit(FILE *input_fp, nal_unit *nalu); 
static int get_unsigned_exp_golomb();
static void decode_slice_header(slice_header *sh);
static void input_read(FILE *input_fp, unsigned char *dest, int size);
static int input_get_bits(int bit_count);
int va_FoolGetFrame(FILE *input_fp, char *frame_buf); 

static unsigned char nal_buf[NAL_BUF_SIZE];
static unsigned char ring_buf[RING_BUF_SIZE];
static int input_remain = 0;
static int ring_pos = 0;
static int nal_pos;
static int nal_bit;
static int frame_no = 0, cur_frame_no = 0;

#define SLICE_NUM 4 
#define RING_MOD  ((RING_BUF_SIZE)-1)
#define HALF_RING ((RING_BUF_SIZE)/2)

#define gnn_advance() do { \
	ring_pos = (ring_pos+1)&RING_MOD; \
	--input_remain; \
	if (ring_pos==0) input_read(input_fp, &ring_buf[HALF_RING],HALF_RING); \
	if (ring_pos==HALF_RING) input_read(input_fp, &ring_buf[0],HALF_RING); \
} while(0)

#define gnn_add_segment(end) do { \
	int size = end-segment_start; \
	if (size>0) { \
		memcpy(&nal_buf[nalu_size],&ring_buf[segment_start],size); \
		nalu_size += size; \
	} \
	segment_start = end&RING_MOD; \
} while(0)

static int input_get_bits(int bit_count) 
{
    int res = 0;
    register unsigned int x = 
        (nal_buf[nal_pos]<<24)|
        (nal_buf[nal_pos+1]<<16)|
        (nal_buf[nal_pos+2]<<8)|
        nal_buf[nal_pos+3];

    res = (x>>(32-bit_count-nal_bit))&((1<<bit_count)-1);
    nal_bit += bit_count;
    nal_pos += nal_bit>>3;
    nal_bit &= 7;

    return res;
}

static int input_get_one_bit() 
{
    int res = (nal_buf[nal_pos]>>(7-nal_bit))&1;

    if (++nal_bit>7) {
        ++nal_pos;
        nal_bit = 0;
    }
    return res;
}

static int get_unsigned_exp_golomb() 
{
    int exp;

    for(exp = 0; !input_get_one_bit(); ++exp);
    
    if (exp)
        return (1<<exp) - 1 + input_get_bits(exp);
    else
        return 0;
}

static void decode_slice_header(slice_header *sh ) 
{
    memset((void*)sh,0,sizeof(slice_header));
    sh->first_mb_in_slice = get_unsigned_exp_golomb(); 
}

static void input_read(FILE *input_fp, unsigned char *dest, int size) 
{
    int count = fread(dest, 1, size, input_fp);

    input_remain += count;
}

static int get_next_nal_unit(FILE *input_fp, nal_unit *nalu)
{
    int i,segment_start;
    int nalu_size = 0;
    int NumBytesInRbsp = 0;

    /* search for the next NALU start
     * here is the sync that the start of the NALU is 0x00000001
     */
    for (;;) {
        if (input_remain<= 4) {
            /* clip restart */
            memset(ring_buf,0,sizeof(char)*RING_BUF_SIZE);
            memset(nal_buf,0,sizeof(char)*NAL_BUF_SIZE);

            fseek(input_fp,0,SEEK_SET);
            input_remain = 0;
            input_read(input_fp, ring_buf, RING_BUF_SIZE);
            ring_pos = 0;
            return 1;
        }
        if ((!ring_buf[ring_pos]) &&
           (!ring_buf[(ring_pos+1)&RING_MOD]) &&
           (!ring_buf[(ring_pos+2)&RING_MOD]) &&
           ( ring_buf[(ring_pos+3)&RING_MOD]==1))
            break;
        gnn_advance();
    }
    
    for(i=0;i<4;++i)
        gnn_advance();

    /* add bytes to the NALU until the end is found */
    segment_start = ring_pos;
    while (input_remain) {
        if ((!ring_buf[ring_pos]) &&
           (!ring_buf[(ring_pos+1)&RING_MOD]) &&
           (!ring_buf[(ring_pos+2)&RING_MOD]))
            break;
        ring_pos = (ring_pos+1)&RING_MOD;
        --input_remain;
        
        if (ring_pos==0) {
            gnn_add_segment(RING_BUF_SIZE);
            input_read(input_fp, &ring_buf[HALF_RING],HALF_RING);
        }

        if (ring_pos==HALF_RING) {
            gnn_add_segment(HALF_RING);
            input_read(input_fp, &ring_buf[0], HALF_RING);
        }
    }

    gnn_add_segment(ring_pos);

    /* read the NAL unit */
    nal_pos = 0; nal_bit = 0;
    nalu->forbidden_zero_bit = input_get_bits(1);
    nalu->nal_ref_idc = input_get_bits(2);
    nalu->nal_unit_type = input_get_bits(5);
    nalu->last_rbsp_byte = &nal_buf[nalu_size-1];
    nalu->NumBytesInNALunit = nalu_size; 

    return 1;
}

int va_FoolGetFrame(FILE *input_fp, char *frame_buf) 
{
    int i = 0, frame_pos = 0;
    static slice_header sh; 
    static nal_unit nalu;

    /* save the current frame number */
    cur_frame_no = frame_no;
    
    /* read the clip , here is the first frame,
     * &let the clip go on frame by frame
     */
    if (!frame_no)
        input_read(input_fp, ring_buf,RING_BUF_SIZE);

    while (get_next_nal_unit(input_fp, &nalu)) {
        if (nalu.nal_unit_type == 1 || nalu.nal_unit_type == 5) {
            decode_slice_header(&sh);
            if (0 == sh.first_mb_in_slice) {
                ++frame_no;
                frame_pos = 0;
            }
            if (frame_no > (cur_frame_no+1))
                break;
            memcpy(frame_buf+frame_pos, nal_buf+1, sizeof(char)*(nalu.NumBytesInNALunit-1));
            frame_pos += nalu.NumBytesInNALunit;
        }
    }
    
    return 1; 
}
