summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjiguoliang <jiguoliang@localhost.localdomain>2011-01-04 17:03:14 +0800
committerjiguoliang <jiguoliang@localhost.localdomain>2011-01-04 17:03:14 +0800
commit858e396217601f1d356515356d79fbb6c057930d (patch)
treea67b4f0c44ef0aa08119b3bb2d17a8468d2b738a
parent1764bd178bd46dcc9756a180579ec5f3db688a93 (diff)
downloadlibva-858e396217601f1d356515356d79fbb6c057930d.tar.gz
add the fool get frame function
-rw-r--r--va/va_fool.c16
-rw-r--r--va/va_fool.h2
-rw-r--r--va/va_getframe.c165
-rw-r--r--va/va_getframe.h25
4 files changed, 205 insertions, 3 deletions
diff --git a/va/va_fool.c b/va/va_fool.c
index 519304d..3df179e 100644
--- a/va/va_fool.c
+++ b/va/va_fool.c
@@ -26,6 +26,7 @@
#include "va.h"
#include "va_backend.h"
#include "va_trace.h"
+#include "va_fool.h"
#include <assert.h>
#include <stdarg.h>
@@ -40,6 +41,7 @@
#include <time.h>
#include "va_fool_264.h"
+#include "va_getframe.c"
/*
@@ -64,7 +66,10 @@
static int fool_decode = 0;
static int fool_encode = 0;
int fool_postp = 0;
+static char clip[1024];
+static char *frame_buf;
+#define MAX_FRAME 16
#define FOOL_CONTEXT_MAX 4
/* per context settings */
static struct _fool_context {
@@ -165,6 +170,8 @@ void va_FoolInit(VADisplay dpy)
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));
if (tmp)
fool_context[fool_index].fool_fp_codedclip = tmp;
@@ -395,7 +402,6 @@ VAStatus va_FoolCreateBuffer (
return 0; /* let driver go ... */
}
-
VAStatus va_FoolMapBuffer (
VADisplay dpy,
VABufferID buf_id, /* in */
@@ -424,12 +430,17 @@ VAStatus va_FoolMapBuffer (
/* expect APP to MapBuffer when get the the coded data */
if (*pbuf && (buf_idx == VAEncCodedBufferType)) { /* it is coded buffer */
/* should read from a clip, here we use the hardcoded h264_720p_nal */
+#if 0
memcpy(*pbuf, &h264_720p_nal[h264_720p_nal_idx], sizeof(VACodedBufferSegment));
h264_720p_nal_idx++;
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;
}
-
return 1; /* don't call into driver */
}
@@ -521,6 +532,7 @@ VAStatus va_FoolUnmapBuffer (
DPY2INDEX(dpy);
if (FOOL_ENCODE(idx) || FOOL_DECODE(idx)) { /* fool buffer creation */
+ free(frame_buf);
return 1;
}
return 0;
diff --git a/va/va_fool.h b/va/va_fool.h
index a3d0a92..1e10523 100644
--- a/va/va_fool.h
+++ b/va/va_fool.h
@@ -25,7 +25,7 @@
#ifndef VA_FOOL_H
#define VA_FOOL_H
-
+#include "va_getframe.h"
void va_FoolInit(VADisplay dpy);
int va_FoolEnd(VADisplay dpy);
diff --git a/va/va_getframe.c b/va/va_getframe.c
new file mode 100644
index 0000000..17b663d
--- /dev/null
+++ b/va/va_getframe.c
@@ -0,0 +1,165 @@
+#define SLICE_NUM 4
+
+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 nal_pos;
+static int nal_bit;
+static FILE *input_fd=NULL;
+
+#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); \
+} 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;
+}
+
+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;
+}
+
+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 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 void input_read(unsigned char *dest, int size) {
+ int count=fread(dest,1,size,input_fd);
+ input_remain+=count;
+}
+
+//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;
+ static slice_header sh;
+ static nal_unit nalu;
+
+ input_open(filename);
+ while(get_next_nal_unit(&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(maxframe && frame_no>maxframe)
+ break;
+ memcpy(frame_buf+frame_pos, nal_buf+1, sizeof(char)*(nalu.NumBytesInNALunit-1));
+ frame_pos += nalu.NumBytesInNALunit;
+ }
+ }
+ fclose(input_fd);
+
+ return 1;
+}
diff --git a/va/va_getframe.h b/va/va_getframe.h
new file mode 100644
index 0000000..44e5009
--- /dev/null
+++ b/va/va_getframe.h
@@ -0,0 +1,25 @@
+#ifndef __NAL_H__
+#define __NAL_H__
+
+#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(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);
+#endif /*__NAL_H__*/