diff options
author | jiguoliang <jiguoliang@localhost.localdomain> | 2011-01-07 18:42:40 +0800 |
---|---|---|
committer | jiguoliang <jiguoliang@localhost.localdomain> | 2011-01-07 18:42:40 +0800 |
commit | e3571f377c6c9340fab3455374dd75a5d147378f (patch) | |
tree | febd38d581118fe80530198cf4c4aff41681793e | |
parent | 858e396217601f1d356515356d79fbb6c057930d (diff) | |
download | libva-e3571f377c6c9340fab3455374dd75a5d147378f.tar.gz |
modify the va_getframe according to austin`s requirement
-rw-r--r-- | va/Makefile.am | 2 | ||||
-rw-r--r-- | va/va_fool.c | 356 | ||||
-rw-r--r-- | va/va_fool.h | 2 | ||||
-rw-r--r-- | va/va_getframe.c | 257 | ||||
-rw-r--r-- | va/va_getframe.h | 4 |
5 files changed, 313 insertions, 308 deletions
diff --git a/va/Makefile.am b/va/Makefile.am index 685fb12..1b8f16f 100644 --- a/va/Makefile.am +++ b/va/Makefile.am @@ -27,7 +27,7 @@ INCLUDES = \ LDADD = \ $(LIBVA_LT_LDFLAGS) -libva_la_SOURCES = va.c va_trace.c va_fool.c +libva_la_SOURCES = va.c va_trace.c va_fool.c va_getframe.c libva_ladir = $(libdir) libva_la_LDFLAGS = $(LDADD) -no-undefined libva_la_LIBADD = $(LIBVA_LIBS) -ldl diff --git a/va/va_fool.c b/va/va_fool.c index 3df179e..1edbd6d 100644 --- a/va/va_fool.c +++ b/va/va_fool.c @@ -39,10 +39,8 @@ #include <sys/stat.h> #include <unistd.h> #include <time.h> - #include "va_fool_264.h" -#include "va_getframe.c" - +#include "va_getframe.h" /* * Do dummy decode/encode, ignore the input data @@ -66,7 +64,7 @@ static int fool_decode = 0; static int fool_encode = 0; int fool_postp = 0; -static char clip[1024]; +FILE *input_fd; static char *frame_buf; #define MAX_FRAME 16 @@ -74,12 +72,12 @@ static char *frame_buf; /* per context settings */ static struct _fool_context { VADisplay dpy; /* should use context as the key */ - + VAProfile fool_profile; /* current profile for buffers */ VAEntrypoint fool_entrypoint; /* current entrypoint */ FILE *fool_fp_codedclip; /* load a clip from disk for fooling encode*/ - + /* all buffers with same type share one malloc-ed memory * bufferID = (buffer numbers with the same type << 8) || type * the malloc-ed memory can be find by fool_buf[bufferID & 0xff] @@ -93,22 +91,22 @@ static struct _fool_context { #define FOOL_DECODE(idx) (fool_decode && (fool_context[idx].fool_entrypoint == VAEntrypointVLD)) #define FOOL_ENCODE(idx) \ -(fool_encode \ - && (fool_context[idx].fool_entrypoint == VAEntrypointEncSlice) \ - && (fool_context[idx].fool_profile >= VAProfileH264Baseline) \ - && (fool_context[idx].fool_profile <= VAProfileH264High)) + (fool_encode \ + && (fool_context[idx].fool_entrypoint == VAEntrypointEncSlice) \ + && (fool_context[idx].fool_profile >= VAProfileH264Baseline) \ + && (fool_context[idx].fool_profile <= VAProfileH264High)) #define DPY2INDEX(dpy) \ int idx; \ - \ - for (idx = 0; idx < FOOL_CONTEXT_MAX; idx++) \ - if (fool_context[idx].dpy == dpy) \ - break; \ - \ - if (idx == FOOL_CONTEXT_MAX) \ - return 0; /* let driver go */ \ +\ +for (idx = 0; idx < FOOL_CONTEXT_MAX; idx++) \ +if (fool_context[idx].dpy == dpy) \ +break; \ +\ +if (idx == FOOL_CONTEXT_MAX) \ +return 0; /* let driver go */ \ /* Prototype declarations (functions defined in va.c) */ @@ -118,30 +116,30 @@ void va_infoMessage(const char *msg, ...); int va_parseConfig(char *env, char *env_value); VAStatus vaBufferInfo( - VADisplay dpy, - VAContextID context, /* in */ - VABufferID buf_id, /* in */ - VABufferType *type, /* out */ - unsigned int *size, /* out */ - unsigned int *num_elements /* out */ -); + VADisplay dpy, + VAContextID context, /* in */ + VABufferID buf_id, /* in */ + VABufferType *type, /* out */ + unsigned int *size, /* out */ + unsigned int *num_elements /* out */ + ); VAStatus vaLockSurface(VADisplay dpy, - VASurfaceID surface, - unsigned int *fourcc, /* following are output argument */ - unsigned int *luma_stride, - unsigned int *chroma_u_stride, - unsigned int *chroma_v_stride, - unsigned int *luma_offset, - unsigned int *chroma_u_offset, - unsigned int *chroma_v_offset, - unsigned int *buffer_name, - void **buffer -); + VASurfaceID surface, + unsigned int *fourcc, /* following are output argument */ + unsigned int *luma_stride, + unsigned int *chroma_u_stride, + unsigned int *chroma_v_stride, + unsigned int *luma_offset, + unsigned int *chroma_u_offset, + unsigned int *chroma_v_offset, + unsigned int *buffer_name, + void **buffer + ); VAStatus vaUnlockSurface(VADisplay dpy, - VASurfaceID surface -); + VASurfaceID surface + ); void va_FoolInit(VADisplay dpy) @@ -160,24 +158,20 @@ void va_FoolInit(VADisplay dpy) fool_postp = 1; va_infoMessage("LIBVA_FOOL_POSTP is on, dummy vaPutSurface\n"); } - - + + if (va_parseConfig("LIBVA_FOOL_DECODE", NULL) == 0) { fool_decode = 1; va_infoMessage("LIBVA_FOOL_DECODE is on, dummy decode\n"); } - + if (va_parseConfig("LIBVA_FOOL_ENCODE", &env_value[0]) == 0) { - FILE *tmp = fopen(env_value, "r"); - memset(clip,0,sizeof(char)*1024); - memcpy(clip,env_value,sizeof(env_value)); + input_fd = fopen(env_value, "r"); - if (tmp) - fool_context[fool_index].fool_fp_codedclip = tmp; - + if (input_fd) + fool_context[fool_index].fool_fp_codedclip = input_fd; fool_encode = 1; - va_infoMessage("LIBVA_FOOL_ENCODE is on, dummy encode\n"); } @@ -189,13 +183,13 @@ void va_FoolInit(VADisplay dpy) int va_FoolEnd(VADisplay dpy) { int i; - + DPY2INDEX(dpy); - + for (i = 0; i < VABufferTypeMax; i++) /* free memory */ if (fool_context[idx].fool_buf[i]) free(fool_context[idx].fool_buf[i]); - + memset(&fool_context[idx], sizeof(struct _fool_context), 0); return 0; } @@ -208,16 +202,16 @@ int va_FoolCodedBuf(VADisplay dpy) int va_FoolCreateConfig( - VADisplay dpy, - VAProfile profile, - VAEntrypoint entrypoint, - VAConfigAttrib *attrib_list, - int num_attribs, - VAConfigID *config_id /* out */ -) + VADisplay dpy, + VAProfile profile, + VAEntrypoint entrypoint, + VAConfigAttrib *attrib_list, + int num_attribs, + VAConfigID *config_id /* out */ + ) { DPY2INDEX(dpy); - + /* call into driver level to allocate real context/surface/buffers, etc */ fool_context[idx].fool_profile = profile; fool_context[idx].fool_entrypoint = entrypoint; @@ -225,13 +219,13 @@ int va_FoolCreateConfig( } static int yuvgen_planar( - int width, int height, - unsigned char *Y_start, int Y_pitch, - unsigned char *U_start, int U_pitch, - unsigned char *V_start, int V_pitch, - int UV_interleave, int box_width, int row_shift, - int field -) + int width, int height, + unsigned char *Y_start, int Y_pitch, + unsigned char *U_start, int U_pitch, + unsigned char *V_start, int V_pitch, + int UV_interleave, int box_width, int row_shift, + int field + ) { int row; @@ -244,33 +238,33 @@ static int yuvgen_planar( /* fill garbage data into the other field */ if (((field == VA_TOP_FIELD) && (row &1)) - || ((field == VA_BOTTOM_FIELD) && ((row &1)==0))) { + || ((field == VA_BOTTOM_FIELD) && ((row &1)==0))) { memset(Y_row, 0xff, width); continue; } - + for (jj=0; jj<width; jj++) { xpos = ((row_shift + jj) / box_width) & 0x1; - + if ((xpos == 0) && (ypos == 0)) Y_row[jj] = 0xeb; if ((xpos == 1) && (ypos == 1)) Y_row[jj] = 0xeb; - + if ((xpos == 1) && (ypos == 0)) Y_row[jj] = 0x10; if ((xpos == 0) && (ypos == 1)) Y_row[jj] = 0x10; } } - + /* copy UV data */ for( row =0; row < height/2; row++) { unsigned short value = 0x80; /* fill garbage data into the other field */ if (((field == VA_TOP_FIELD) && (row &1)) - || ((field == VA_BOTTOM_FIELD) && ((row &1)==0))) { + || ((field == VA_BOTTOM_FIELD) && ((row &1)==0))) { value = 0xff; } @@ -281,7 +275,7 @@ static int yuvgen_planar( } else { unsigned char *U_row = U_start + row * U_pitch; unsigned char *V_row = V_start + row * V_pitch; - + memset (U_row,value,width/2); memset (V_row,value,width/2); } @@ -292,13 +286,13 @@ static int yuvgen_planar( int va_FoolCreateSurfaces( - VADisplay dpy, - int width, - int height, - int format, - int num_surfaces, - VASurfaceID *surfaces /* out */ -) + VADisplay dpy, + int width, + int height, + int format, + int num_surfaces, + VASurfaceID *surfaces /* out */ + ) { int i; unsigned int fourcc; /* following are output argument */ @@ -315,73 +309,73 @@ int va_FoolCreateSurfaces( int box_width = num_surfaces/2; int row_shift = 0; VAStatus va_status; - + DPY2INDEX(dpy); if (FOOL_DECODE(idx)) { - /* call into driver level to allocate real context/surface/buffers, etc - * fill in the YUV data, will be overwrite if it is encode context - */ - for (i = 0; i < num_surfaces; i++) { - /* fool decoder: fill with auto-generated YUV data */ - va_status = vaLockSurface(dpy, surfaces[i], &fourcc, - &luma_stride, &chroma_u_stride, &chroma_v_stride, - &luma_offset, &chroma_u_offset, &chroma_v_offset, - &buffer_name, &buffer); - - if (va_status != VA_STATUS_SUCCESS) - return 0; - - if (!buffer) { - vaUnlockSurface(dpy, surfaces[i]); - return 0; - } - - Y_data = buffer; - - /* UV should be same for NV12 */ - U_data = buffer + chroma_u_offset; - V_data = buffer + chroma_v_offset; - - yuvgen_planar(width, height, - Y_data, luma_stride, - U_data, chroma_v_stride, - V_data, chroma_v_stride, - (fourcc==VA_FOURCC_NV12), - box_width, row_shift, 0); - - vaUnlockSurface(dpy, surfaces[i]); - - row_shift++; - if (row_shift==(2*box_width)) - row_shift= 0; - } - return 0; /* the return value is ignored */ + /* call into driver level to allocate real context/surface/buffers, etc + * fill in the YUV data, will be overwrite if it is encode context + */ + for (i = 0; i < num_surfaces; i++) { + /* fool decoder: fill with auto-generated YUV data */ + va_status = vaLockSurface(dpy, surfaces[i], &fourcc, + &luma_stride, &chroma_u_stride, &chroma_v_stride, + &luma_offset, &chroma_u_offset, &chroma_v_offset, + &buffer_name, &buffer); + + if (va_status != VA_STATUS_SUCCESS) + return 0; + + if (!buffer) { + vaUnlockSurface(dpy, surfaces[i]); + return 0; + } + + Y_data = buffer; + + /* UV should be same for NV12 */ + U_data = buffer + chroma_u_offset; + V_data = buffer + chroma_v_offset; + + yuvgen_planar(width, height, + Y_data, luma_stride, + U_data, chroma_v_stride, + V_data, chroma_v_stride, + (fourcc==VA_FOURCC_NV12), + box_width, row_shift, 0); + + vaUnlockSurface(dpy, surfaces[i]); + + row_shift++; + if (row_shift==(2*box_width)) + row_shift= 0; + } + return 0; /* the return value is ignored */ } return 0; /* the return value is ignored */ } VAStatus va_FoolCreateBuffer ( - VADisplay dpy, - VAContextID context, /* in */ - VABufferType type, /* in */ - unsigned int size, /* in */ - unsigned int num_elements, /* in */ - void *data, /* in */ - VABufferID *buf_id /* out */ -) + VADisplay dpy, + VAContextID context, /* in */ + VABufferType type, /* in */ + unsigned int size, /* in */ + unsigned int num_elements, /* in */ + void *data, /* in */ + VABufferID *buf_id /* out */ + ) { DPY2INDEX(dpy); if (FOOL_ENCODE(idx) || FOOL_DECODE(idx)) { /* fool buffer creation */ int new_size = size * num_elements; - + if (type == VAEncCodedBufferType) /* only a VACodedBufferSegment */ new_size = sizeof(VACodedBufferSegment); - - if (fool_context[idx].fool_buf_size[type] == 0) - fool_context[idx].fool_buf[type] = calloc(1, new_size); - else if (fool_context[idx].fool_buf_size[type] <= new_size) + + if (fool_context[idx].fool_buf_size[type] == 0) + fool_context[idx].fool_buf[type] = calloc(1, new_size); + else if (fool_context[idx].fool_buf_size[type] <= new_size) fool_context[idx].fool_buf[type] = realloc(fool_context[idx].fool_buf, new_size); if (fool_context[idx].fool_buf[type] == NULL) { @@ -395,18 +389,18 @@ VAStatus va_FoolCreateBuffer ( */ fool_context[idx].fool_buf_count[type]++; *buf_id = (fool_context[idx].fool_buf_count[type] << 8) | type; - + return 1; /* don't call into driver */ } - + return 0; /* let driver go ... */ } - + VAStatus va_FoolMapBuffer ( - VADisplay dpy, - VABufferID buf_id, /* in */ - void **pbuf /* out */ -) + VADisplay dpy, + VABufferID buf_id, /* in */ + void **pbuf /* out */ + ) { VABufferType type; unsigned int size; @@ -415,11 +409,11 @@ VAStatus va_FoolMapBuffer ( if (FOOL_ENCODE(idx) || FOOL_DECODE(idx)) { /* fool buffer creation */ unsigned int buf_idx = buf_id & 0xff; - - /*Image buffer?*/ - vaBufferInfo(dpy, fool_context[idx].context, buf_id, &type, &size, &num_elements); - if (type == VAImageBufferType && FOOL_ENCODE(idx)) - return 0; + + /*Image buffer?*/ + vaBufferInfo(dpy, fool_context[idx].context, buf_id, &type, &size, &num_elements); + if (type == VAImageBufferType && FOOL_ENCODE(idx)) + return 0; /* buf_id is the buffer type */ if (fool_context[idx].fool_buf[buf_idx] != NULL) @@ -436,45 +430,45 @@ VAStatus va_FoolMapBuffer ( if (h264_720p_nal_idx == H264_720P_NAL_NUMBER) h264_720p_nal_idx = 0; /* reset to 0 */ #endif - frame_buf=malloc(MAX_FRAME*SLICE_NUM*NAL_BUF_SIZE*sizeof(char)); - memset(frame_buf,0,SLICE_NUM*NAL_BUF_SIZE); - va_FoolGetFrame( clip , 16, frame_buf); - *pbuf=frame_buf; + frame_buf = malloc(MAX_FRAME*SLICE_NUM*NAL_BUF_SIZE*sizeof(char)); + memset(frame_buf,0,SLICE_NUM*NAL_BUF_SIZE); + va_FoolGetFrame(frame_buf); + *pbuf=frame_buf; } return 1; /* don't call into driver */ } - + return 0; /* let driver go ... */ } int va_FoolBeginPicture( - VADisplay dpy, - VAContextID context, - VASurfaceID render_target -) + VADisplay dpy, + VAContextID context, + VASurfaceID render_target + ) { DPY2INDEX(dpy); - + if (FOOL_ENCODE(idx) || FOOL_DECODE(idx)) { - if (fool_context[idx].context == 0) - fool_context[idx].context = context; + if (fool_context[idx].context == 0) + fool_context[idx].context = context; return 1; /* don't call into driver level */ } - + return 0; /* let driver go ... */ } int va_FoolRenderPicture( - VADisplay dpy, - VAContextID context, - VABufferID *buffers, - int num_buffers -) + VADisplay dpy, + VAContextID context, + VABufferID *buffers, + int num_buffers + ) { DPY2INDEX(dpy); - + if (FOOL_ENCODE(idx) || FOOL_DECODE(idx)) return 1; /* don't call into driver level */ @@ -483,9 +477,9 @@ int va_FoolRenderPicture( int va_FoolEndPicture( - VADisplay dpy, - VAContextID context -) + VADisplay dpy, + VAContextID context + ) { DPY2INDEX(dpy); @@ -510,14 +504,14 @@ int va_FoolEndPicture( } int va_FoolSyncSurface( - VADisplay dpy, - VASurfaceID render_target) + VADisplay dpy, + VASurfaceID render_target) { DPY2INDEX(dpy); /*Fill in black and white squares. */ if (FOOL_DECODE(idx) || FOOL_DECODE(idx)) { - return 1; + return 1; } return 0; @@ -525,32 +519,32 @@ int va_FoolSyncSurface( } VAStatus va_FoolUnmapBuffer ( - VADisplay dpy, - VABufferID buf_id /* in */ -) + VADisplay dpy, + VABufferID buf_id /* in */ + ) { DPY2INDEX(dpy); if (FOOL_ENCODE(idx) || FOOL_DECODE(idx)) { /* fool buffer creation */ - free(frame_buf); - return 1; + free(frame_buf); + return 1; } return 0; } VAStatus va_FoolQuerySubpictureFormats ( - VADisplay dpy, - VAImageFormat *format_list, - unsigned int *flags, - unsigned int *num_formats -) + VADisplay dpy, + VAImageFormat *format_list, + unsigned int *flags, + unsigned int *num_formats + ) { DPY2INDEX(dpy); if (FOOL_ENCODE(idx) || FOOL_DECODE(idx)) { - if (num_formats) - *num_formats = 0; - return 1; + if (num_formats) + *num_formats = 0; + return 1; } return 0; } diff --git a/va/va_fool.h b/va/va_fool.h index 1e10523..3bd7d18 100644 --- a/va/va_fool.h +++ b/va/va_fool.h @@ -25,12 +25,10 @@ #ifndef VA_FOOL_H #define VA_FOOL_H -#include "va_getframe.h" void va_FoolInit(VADisplay dpy); int va_FoolEnd(VADisplay dpy); - int va_FoolCodedBuf(VADisplay dpy); int va_FoolCreateConfig( VADisplay dpy, diff --git a/va/va_getframe.c b/va/va_getframe.c index 17b663d..e3a0661 100644 --- a/va/va_getframe.c +++ b/va/va_getframe.c @@ -1,165 +1,178 @@ -#define SLICE_NUM 4 +#include <string.h> +#include <stdio.h> +#include "va_getframe.h" static unsigned char nal_buf[NAL_BUF_SIZE]; static unsigned char ring_buf[RING_BUF_SIZE]; -static int input_remain; -static int ring_pos; +static int input_remain = 0; +static int ring_pos = 0; static int nal_pos; static int nal_bit; -static FILE *input_fd=NULL; +extern FILE *input_fd; +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(&ring_buf[HALF_RING],HALF_RING); \ - if(ring_pos==HALF_RING) input_read(&ring_buf[0],HALF_RING); \ + ring_pos = (ring_pos+1)&RING_MOD; \ + --input_remain; \ + if(ring_pos==0) input_read(&ring_buf[HALF_RING],HALF_RING); \ + if(ring_pos==HALF_RING) input_read(&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; \ + 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_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; } -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; +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; } -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; +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; } -void decode_slice_header(slice_header *sh ) { - memset((void*)sh,0,sizeof(slice_header)); - sh->first_mb_in_slice =get_unsigned_exp_golomb(); +void decode_slice_header(slice_header *sh ) +{ + memset((void*)sh,0,sizeof(slice_header)); + sh->first_mb_in_slice = get_unsigned_exp_golomb(); } -static int get_next_nal_unit(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) return 0; - - 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(&ring_buf[HALF_RING],HALF_RING); - } - if(ring_pos==HALF_RING) { - gnn_add_segment(HALF_RING); - input_read(&ring_buf[0],HALF_RING); - } - } - - gnn_add_segment(ring_pos); - if(!nalu_size) - fclose(input_fd); - - // 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; +static void input_read(unsigned char *dest, int size) +{ + int count = fread(dest,1,size,input_fd); + input_remain += count; } -static int input_open(char *filename) { - if(input_fd) { - fprintf(stderr,"input_open: file already opened\n"); - return 0; - } - input_fd=fopen(filename,"rb"); - if(!input_fd) { - perror("input_open: cannot open file"); - return 0; - } - input_remain=0; - input_read(ring_buf,RING_BUF_SIZE); - ring_pos=0; - - return 1; -} +static int get_next_nal_unit(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_fd,0,SEEK_SET); + input_remain = 0; + input_read(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(); -static void input_read(unsigned char *dest, int size) { - int count=fread(dest,1,size,input_fd); - input_remain+=count; + // 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(&ring_buf[HALF_RING],HALF_RING); + } + if(ring_pos==HALF_RING) + { + gnn_add_segment(HALF_RING); + input_read(&ring_buf[0],HALF_RING); + } + } + + gnn_add_segment(ring_pos); + if(!nalu_size) + fclose(input_fd); + + // 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; } -//get the frame address -int va_FoolGetFrame(char *filename, int maxframe, char *frame_buf) { - int i, size_info, frame_pos=0; - int frame_no=0; +int va_FoolGetFrame(char *frame_buf) +{ + int i = 0, frame_pos = 0; static slice_header sh; static nal_unit nalu; - input_open(filename); + //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(ring_buf,RING_BUF_SIZE); + while(get_next_nal_unit(&nalu)) { - if(nalu.nal_unit_type==1 || nalu.nal_unit_type==5) { + if(nalu.nal_unit_type == 1 || nalu.nal_unit_type == 5) + { decode_slice_header(&sh); - if(0==sh.first_mb_in_slice) + if(0 == sh.first_mb_in_slice) { ++frame_no; - frame_pos=0; + frame_pos = 0; } - if(maxframe && frame_no>maxframe) + 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; } } - fclose(input_fd); - - return 1; + //close the env_value clip ;if some other area use this clip need to open it again + fclose(input_fd); + return 1; } diff --git a/va/va_getframe.h b/va/va_getframe.h index 44e5009..399c8b0 100644 --- a/va/va_getframe.h +++ b/va/va_getframe.h @@ -1,6 +1,7 @@ #ifndef __NAL_H__ #define __NAL_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! @@ -18,8 +19,7 @@ typedef struct _nal_unit { static int get_next_nal_unit(nal_unit *nalu); static int get_unsigned_exp_golomb(); static void decode_slice_header(slice_header *sh); -static int input_open(char *filename); static void input_read(unsigned char *dest, int size); static int input_get_bits(int bit_count); -int va_FoolGetFrame(char *filename, int maxframe, char *frame_buf); +int va_FoolGetFrame(char *frame_buf); #endif /*__NAL_H__*/ |