分享

xvid 数据编码和解码

 guitarhua 2013-11-14

由于视频开发的需求,封装xvid c调用接口,使之优雅易用
我已经对pc camera视频流(RGB)进行尝试,编码之后传输到远程主机进行解码回放,效果不错
具体的xvid的参数可以进一步优化,这里只是提供简单的范例
1. xvid 解码

 1 
 2 /*
 3     encode.cpp
 4     xvid 编码YUV数据,为进一步传输提供准备
 5 
 6 */
 7 #ifndef _XVID_ENCODE_H
 8 #define _XVID_ENCODE_H
 9 
10 #include <xvid.h>
11 
12 struct DecodeInfo{
13     unsigned short    width;
14     unsigned short  height;        
15     void (*after_decode)(void * data,unsigned int size,int width,int height,void* user);
16     void * user;
17 };
18 
19 
20 class Xvid_Decoder{
21     
22 public:
23     Xvid_Decoder(){ 
24     }
25     bool            Open();
26     void            Close();
27     DecodeInfo &    GetDecodeInfo(){    return _dec_info;}
28     void            decode(void *data,unsigned int size);
29     static    void    xvid_global_init();
30     xvid_dec_create_t&    GetHandle(){    return _xvid_dec_create;}
31 private:
32     int                xvid_dec(unsigned char *bitstream,int bs_size,unsigned char *image);
33 private:
34     DecodeInfo    _dec_info;
35     void*        _dec_handle;
36     char         _image[1024*768*3];
37     xvid_dec_create_t _xvid_dec_create;    
38 };
39 
40 #endif
41 

 

 

 1 
 2 /*
 3     encode.cpp
 4     xvid 编码YUV数据,为进一步传输提供准备
 5 
 6 */
 7 #include "xvid_dec.h"
 8 #include <windows.h>
 9 
10 //////////////////////////////////////////////////////////////////////////
11 
12 
13 void Xvid_Decoder::Close(){
14     int xerr;    
15     /* Destroy the encoder instance */
16     xerr = xvid_decore(_dec_handle, XVID_ENC_DESTROY, NULL, NULL);    
17 }
18 
19 void Xvid_Decoder::xvid_global_init(){
20     /*------------------------------------------------------------------------
21      * XviD core initialization
22      *----------------------------------------------------------------------*/
23     xvid_gbl_init_t xvid_gbl_init;
24     memset(&xvid_gbl_init, 0sizeof(xvid_gbl_init));
25     xvid_gbl_init.version = XVID_VERSION;
26     xvid_gbl_init.cpu_flags = XVID_CPU_FORCE;
27     /* Initialize XviD core -- Should be done once per __process__ */
28     xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL);
29 }
30 
31 bool Xvid_Decoder::Open(){
32     int ret;    
33     
34     /*------------------------------------------------------------------------
35      * XviD encoder initialization
36      *----------------------------------------------------------------------*/
37     int width,height;
38     width = _xvid_dec_create.width ;
39     height = _xvid_dec_create.height;
40     memset(&_xvid_dec_create, 0sizeof(xvid_dec_create_t));
41     _xvid_dec_create.version = XVID_VERSION;
42 
43     /* Width and Height of input frames */
44     _xvid_dec_create.width = width;
45     _xvid_dec_create.height = height;
46 
47     ret = xvid_decore(NULL, XVID_DEC_CREATE, &_xvid_dec_create, NULL);
48     _dec_handle = _xvid_dec_create.handle;
49     return true;
50 }
51 
52 void Xvid_Decoder::decode(void * data,unsigned int size){
53     int ret;
54     ret = xvid_dec((unsigned char*)data,(int)size,(unsigned char *)_image);    
55     if (ret >0)
56         _dec_info.after_decode(_image,(unsigned int)ret,(int)_xvid_dec_create.width,(int)_xvid_dec_create.height,_dec_info.user);
57 }
58 
59 /*
60 raw xvid_encode procedure
61 */
62 int    Xvid_Decoder::xvid_dec(unsigned char *bitstream,int bs_size,unsigned char *image)
63 {
64     int ret;
65     xvid_dec_frame_t xvid_dec_frame;
66 
67     /* Reset all structures */
68     memset(&xvid_dec_frame, 0sizeof(xvid_dec_frame_t));
69     /* Set version */
70     xvid_dec_frame.version = XVID_VERSION;
71 //    xvid_dec_stats->version = XVID_VERSION;
72 
73     /* No general flags to set */
74     xvid_dec_frame.general          = 0;
75 
76     /* Input stream */
77     xvid_dec_frame.bitstream        = bitstream;
78     xvid_dec_frame.length           = bs_size;
79 
80     /* Output frame structure */
81     xvid_dec_frame.output.plane[0]  = image;
82     xvid_dec_frame.output.stride[0= _xvid_dec_create.width  *3;
83     xvid_dec_frame.output.csp = XVID_CSP_BGR;
84 
85     ret = xvid_decore(_dec_handle, XVID_DEC_DECODE, &xvid_dec_frame, NULL);
86     return(ret);    
87 }
88 
89 
90 

2. xvid 编码
 1 
 2 /*
 3     encode.cpp
 4     xvid 编码YUV数据,为进一步传输提供准备
 5 
 6 */
 7 #ifndef _XVID_ENCODE_H
 8 #define _XVID_ENCODE_H
 9 
10 #include <xvid.h>
11 #include <nv.h>
12 
13 
14 
15 struct EncodeInfo{
16     unsigned short    width;
17     unsigned short  height;        
18     void (*after_encode)(void * data,unsigned int size,void* user);
19     void * user;
20 };
21 
22 class Xvid_Encoder:public NVObject{
23 public:
24     Xvid_Encoder(){ _closed = true;
25     }
26     bool            Open();
27     void            Close();
28     EncodeInfo &    GetEncodeInfo(){    return _enc_info;}
29     void            encode(void *data,unsigned int size);
30     static    void    xvid_global_init();
31     int                xvid_enc(unsigned char *image,unsigned char *bitstream);
32 private:
33     EncodeInfo    _enc_info;
34     void*        _enc_handle;
35     char         _bitstream[1024*100];
36     bool        _closed;
37     
38 
39 };
40 
41 #endif
42 
  1 
  2 /*
  3     encode.cpp
  4     xvid 编码YUV数据,为进一步传输提供准备
  5 
  6 */
  7 #include "encode.h"
  8 #include <windows.h>
  9 
 10 
 11 static const int motion_presets[] = {
 12     /* quality 0 */
 13     0,
 14         
 15         /* quality 1 */
 16         XVID_ME_ADVANCEDDIAMOND16,
 17         
 18         /* quality 2 */
 19         XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16,
 20         
 21         /* quality 3 */
 22         XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 |
 23         XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8,
 24         
 25         /* quality 4 */
 26         XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 |
 27         XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8 |
 28         XVID_ME_CHROMA_PVOP | XVID_ME_CHROMA_BVOP,
 29         
 30         /* quality 5 */
 31         XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 |
 32         XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8 |
 33         XVID_ME_CHROMA_PVOP | XVID_ME_CHROMA_BVOP,
 34         
 35         /* quality 6 */
 36         XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 | XVID_ME_EXTSEARCH16 |
 37         XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8 | XVID_ME_EXTSEARCH8 |
 38         XVID_ME_CHROMA_PVOP | XVID_ME_CHROMA_BVOP,
 39         
 40 };
 41 #define ME_ELEMENTS (sizeof(motion_presets)/sizeof(motion_presets[0]))
 42 
 43 static const int vop_presets[] = {
 44     /* quality 0 */
 45     0,
 46         
 47     /* quality 1 */
 48     0,
 49 
 50     /* quality 2 */
 51     XVID_VOP_HALFPEL,
 52 
 53     /* quality 3 */
 54     XVID_VOP_HALFPEL | XVID_VOP_INTER4V,
 55 
 56     /* quality 4 */
 57     XVID_VOP_HALFPEL | XVID_VOP_INTER4V,
 58 
 59     /* quality 5 */
 60     XVID_VOP_HALFPEL | XVID_VOP_INTER4V |
 61     XVID_VOP_TRELLISQUANT,
 62 
 63     /* quality 6 */
 64     XVID_VOP_HALFPEL | XVID_VOP_INTER4V |
 65     XVID_VOP_TRELLISQUANT | XVID_VOP_HQACPRED,
 66 
 67 };
 68 #define VOP_ELEMENTS (sizeof(vop_presets)/sizeof(vop_presets[0]))
 69 
 70 //////////////////////////////////////////////////////////////////////////
 71 #define MAX_ZONES   64
 72 
 73 /* Maximum number of frames to encode */
 74 #define ABS_MAXFRAMENR 9999
 75 
 76 static int ARG_STATS = 0;
 77 static int ARG_DUMP = 0;
 78 static int ARG_LUMIMASKING = 0;
 79 static int ARG_BITRATE = 0;
 80 static int ARG_SINGLE = 0;
 81 static char *ARG_PASS1 = 0;
 82 static char *ARG_PASS2 = 0;
 83 static int ARG_QUALITY = ME_ELEMENTS - 1;
 84 static float ARG_FRAMERATE = 25.00f;
 85 static int ARG_MAXFRAMENR = ABS_MAXFRAMENR;
 86 static int ARG_MAXKEYINTERVAL = 0;
 87 static char *ARG_INPUTFILE = NULL;
 88 static int ARG_INPUTTYPE = 0;
 89 static int ARG_SAVEMPEGSTREAM = 0;
 90 static int ARG_SAVEINDIVIDUAL = 0;
 91 static char *ARG_OUTPUTFILE = NULL;
 92 
 93 static int ARG_BQRATIO = 150;
 94 static int ARG_BQOFFSET = 100;
 95 static int ARG_MAXBFRAMES = 0;
 96 static int ARG_PACKED = 0;
 97 
 98 static int ARG_VOPDEBUG = 0;
 99 static int ARG_GMC = 0;
100 static int ARG_INTERLACING = 0;
101 static int ARG_QPEL = 0;
102 static int ARG_CLOSED_GOP = 0;
103 
104 #ifndef READ_PNM
105 #define IMAGE_SIZE(x,y) ((x)*(y)*3/2)
106 #else
107 #define IMAGE_SIZE(x,y) ((x)*(y)*3)
108 #endif
109 
110 #define MAX(A,B) ( ((A)>(B)) ? (A) : (B) )
111 #define SMALL_EPS (1e-10)
112 
113 #define SWAP(a) ( (((a)&0x000000ff)<<24) | (((a)&0x0000ff00)<<8) | \
114 (((a)&0x00ff0000)>>8)  | (((a)&0xff000000)>>24) )
115 
116 
117 //////////////////////////////////////////////////////////////////////////
118 
119 
120 void Xvid_Encoder::Close(){
121     int xerr;    
122     NVMutexLock lock(_lock);
123 
124     _closed = true;
125     /* Destroy the encoder instance */
126     xerr = xvid_encore(_enc_handle, XVID_ENC_DESTROY, NULL, NULL);    
127 
128 }
129 
130 void Xvid_Encoder::xvid_global_init(){
131     /*------------------------------------------------------------------------
132      * XviD core initialization
133      *----------------------------------------------------------------------*/
134     xvid_gbl_init_t xvid_gbl_init;
135     memset(&xvid_gbl_init, 0sizeof(xvid_gbl_init));
136     xvid_gbl_init.version = XVID_VERSION;
137     xvid_gbl_init.cpu_flags = XVID_CPU_FORCE;
138     /* Initialize XviD core -- Should be done once per __process__ */
139     xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL);
140 }
141 
142 bool Xvid_Encoder::Open(){
143     int xerr;        
144     xvid_enc_create_t xvid_enc_create;
145     _closed = false;
146     /*------------------------------------------------------------------------
147      * XviD encoder initialization
148      *----------------------------------------------------------------------*/
149     memset(&xvid_enc_create, 0sizeof(xvid_enc_create));
150     xvid_enc_create.version = XVID_VERSION;
151 
152     /* Width and Height of input frames */
153     xvid_enc_create.width = GetEncodeInfo().width;
154     xvid_enc_create.height = GetEncodeInfo().height;
155     xvid_enc_create.profile = XVID_PROFILE_AS_L4;
156 
157     /* init plugins  */
158     /*
159     xvid_enc_create.zones = ZONES;
160     xvid_enc_create.num_zones = NUM_ZONES;
161 
162     xvid_enc_create.plugins = plugins;
163     xvid_enc_create.num_plugins = 0;
164     */
165 
166 
167     /* No fancy thread tests */
168     xvid_enc_create.num_threads = 0;
169 
170     /* Frame rate - Do some quick float fps = fincr/fbase hack */    
171     xvid_enc_create.fincr = 1;
172     xvid_enc_create.fbase = (int10;
173     /* Maximum key frame interval */
174     xvid_enc_create.max_key_interval = (int)-1;    //--default 10s
175     /* Bframes settings */
176     xvid_enc_create.max_bframes = ARG_MAXBFRAMES;
177     xvid_enc_create.bquant_ratio = ARG_BQRATIO;
178     xvid_enc_create.bquant_offset = ARG_BQOFFSET;
179 
180     /* Dropping ratio frame -- we don't need that */
181     xvid_enc_create.frame_drop_ratio = 0;
182     /* Global encoder options */
183     xvid_enc_create.global = 0;
184 
185     if (ARG_PACKED)
186         xvid_enc_create.global |= XVID_GLOBAL_PACKED;
187 
188     if (ARG_CLOSED_GOP)
189         xvid_enc_create.global |= XVID_GLOBAL_CLOSED_GOP;
190 
191     if (ARG_STATS)
192         xvid_enc_create.global |= XVID_GLOBAL_EXTRASTATS_ENABLE;
193 
194     /* I use a small value here, since will not encode whole movies, but short clips */
195     xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL);
196     _enc_handle = xvid_enc_create.handle;
197     return true;
198 }
199 
200 void Xvid_Encoder::encode(void * data,unsigned int size){
201     int ret;    
202     _lock.Lock();
203     if( _closed ){
204         _lock.Unlock();
205         return;
206     }
207     ret = xvid_enc((unsigned char*)data,(unsigned char *)_bitstream);        
208     _lock.Unlock();
209     if (ret >0)
210         _enc_info.after_encode(_bitstream,(unsigned int)ret,_enc_info.user);
211     
212 }
213 
214 /*
215 raw xvid_encode procedure
216 */
217 int Xvid_Encoder::xvid_enc(unsigned char *image,unsigned char *bitstream)
218 {
219     int ret;    
220     xvid_enc_frame_t xvid_enc_frame;
221     xvid_enc_stats_t xvid_enc_stats;
222     
223     /* Version for the frame and the stats */
224     memset(&xvid_enc_frame, 0sizeof(xvid_enc_frame));
225     xvid_enc_frame.version = XVID_VERSION;
226     
227     memset(&xvid_enc_stats, 0sizeof(xvid_enc_stats));
228     xvid_enc_stats.version = XVID_VERSION;
229     
230     /* Bind output buffer */
231     xvid_enc_frame.bitstream = bitstream;
232     xvid_enc_frame.length = -1;
233     
234     /* Initialize input image fields */
235     xvid_enc_frame.input.plane[0= image;
236     xvid_enc_frame.input.csp = XVID_CSP_BGR;
237     xvid_enc_frame.input.stride[0= _enc_info.width*3;
238 
239     
240     /* Set up core's general features */
241     xvid_enc_frame.vol_flags = 0;
242     
243     /* Set up core's general features */
244     xvid_enc_frame.vop_flags = vop_presets[ARG_QUALITY-2];
245     
246     /* Frame type -- let core decide for us */
247     xvid_enc_frame.type = XVID_TYPE_AUTO;
248     
249     /* Force the right quantizer -- It is internally managed by RC plugins */
250     xvid_enc_frame.quant = 0;
251     
252     /* Set up motion estimation flags */
253     xvid_enc_frame.motion = motion_presets[ARG_QUALITY-2];
254     
255     /* We don't use special matrices */
256     xvid_enc_frame.quant_intra_matrix = NULL;
257     xvid_enc_frame.quant_inter_matrix = NULL;
258     
259     /* Encode the frame */
260     ret = xvid_encore(_enc_handle, XVID_ENC_ENCODE, &xvid_enc_frame,NULL);
261     //    &xvid_enc_stats);
262     //--判别是否是关键帧
263     //*key = (xvid_enc_frame.out_flags & XVID_KEYFRAME);
264     //*stats_type = xvid_enc_stats.type;
265     //*stats_quant = xvid_enc_stats.quant;
266     //*stats_length = xvid_enc_stats.length;
267     //sse[0] = xvid_enc_stats.sse_y;
268     //sse[1] = xvid_enc_stats.sse_u;
269     //sse[2] = xvid_enc_stats.sse_v;
270     
271     return (ret);
272 }
273 
274 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多