由于视频开发的需求,封装xvid c调用接口,使之优雅易用
我已经对pc camera视频流(RGB)进行尝试,编码之后传输到远程主机进行解码回放,效果不错
具体的xvid的参数可以进一步优化,这里只是提供简单的范例
1. xvid 解码
2
7#ifndef_XVID_ENCODE_H
8#define_XVID_ENCODE_H
9
10#include<xvid.h>
11
12structDecodeInfo{
13unsignedshortwidth;
14unsignedshortheight;
15void(*after_decode)(void*data,unsignedintsize,intwidth,intheight,void*user);
16void*user;
17};
18
19
20classXvid_Decoder{
21
22public:
23Xvid_Decoder(){
24}
25boolOpen();
26voidClose();
27DecodeInfo&GetDecodeInfo(){return_dec_info;}
28voiddecode(void*data,unsignedintsize);
29staticvoidxvid_global_init();
30xvid_dec_create_t&GetHandle(){return_xvid_dec_create;}
31private:
32intxvid_dec(unsignedchar*bitstream,intbs_size,unsignedchar*image);
33private:
34DecodeInfo_dec_info;
35void*_dec_handle;
36char_image[1024*768*3];
37xvid_dec_create_t_xvid_dec_create;
38};
39
40#endif
411
2
7#include"xvid_dec.h"
8#include<windows.h>
9
10//////////////////////////////////////////////////////////////////////////
11
12
13voidXvid_Decoder::Close(){
14intxerr;
15
16xerr=xvid_decore(_dec_handle,XVID_ENC_DESTROY,NULL,NULL);
17}
18
19voidXvid_Decoder::xvid_global_init(){
20
23xvid_gbl_init_txvid_gbl_init;
24memset(&xvid_gbl_init,0,sizeof(xvid_gbl_init));
25xvid_gbl_init.version=XVID_VERSION;
26xvid_gbl_init.cpu_flags=XVID_CPU_FORCE;
27
28xvid_global(NULL,XVID_GBL_INIT,&xvid_gbl_init,NULL);
29}
30
31boolXvid_Decoder::Open(){
32intret;
33
34
37intwidth,height;
38width=_xvid_dec_create.width;
39height=_xvid_dec_create.height;
40memset(&_xvid_dec_create,0,sizeof(xvid_dec_create_t));
41_xvid_dec_create.version=XVID_VERSION;
42
43
44_xvid_dec_create.width=width;
45_xvid_dec_create.height=height;
46
47ret=xvid_decore(NULL,XVID_DEC_CREATE,&_xvid_dec_create,NULL);
48_dec_handle=_xvid_dec_create.handle;
49returntrue;
50}
51
52voidXvid_Decoder::decode(void*data,unsignedintsize){
53intret;
54ret=xvid_dec((unsignedchar*)data,(int)size,(unsignedchar*)_image);
55if(ret>0)
56_dec_info.after_decode(_image,(unsignedint)ret,(int)_xvid_dec_create.width,(int)_xvid_dec_create.height,_dec_info.user);
57}
58
59
62intXvid_Decoder::xvid_dec(unsignedchar*bitstream,intbs_size,unsignedchar*image)
63{
64intret;
65xvid_dec_frame_txvid_dec_frame;
66
67
68memset(&xvid_dec_frame,0,sizeof(xvid_dec_frame_t));
69
70xvid_dec_frame.version=XVID_VERSION;
71//xvid_dec_stats->version=XVID_VERSION;
72
73
74xvid_dec_frame.general=0;
75
76
77xvid_dec_frame.bitstream=bitstream;
78xvid_dec_frame.length=bs_size;
79
80
81xvid_dec_frame.output.plane[0]=image;
82xvid_dec_frame.output.stride[0]=_xvid_dec_create.width*3;
83xvid_dec_frame.output.csp=XVID_CSP_BGR;
84
85ret=xvid_decore(_dec_handle,XVID_DEC_DECODE,&xvid_dec_frame,NULL);
86return(ret);
87}
88
89
90
2. xvid 编码
1
2
7#ifndef_XVID_ENCODE_H
8#define_XVID_ENCODE_H
9
10#include<xvid.h>
11#include<nv.h>
12
13
14
15structEncodeInfo{
16unsignedshortwidth;
17unsignedshortheight;
18void(*after_encode)(void*data,unsignedintsize,void*user);
19void*user;
20};
21
22classXvid_Encoder:publicNVObject{
23public:
24Xvid_Encoder(){_closed=true;
25}
26boolOpen();
27voidClose();
28EncodeInfo&GetEncodeInfo(){return_enc_info;}
29voidencode(void*data,unsignedintsize);
30staticvoidxvid_global_init();
31intxvid_enc(unsignedchar*image,unsignedchar*bitstream);
32private:
33EncodeInfo_enc_info;
34void*_enc_handle;
35char_bitstream[1024*100];
36bool_closed;
37
38
39};
40
41#endif
421
2
7#include"encode.h"
8#include<windows.h>
9
10
11staticconstintmotion_presets[]={
12
130,
14
15
16XVID_ME_ADVANCEDDIAMOND16,
17
18
19XVID_ME_ADVANCEDDIAMOND16|XVID_ME_HALFPELREFINE16,
20
21
22XVID_ME_ADVANCEDDIAMOND16|XVID_ME_HALFPELREFINE16|
23XVID_ME_ADVANCEDDIAMOND8|XVID_ME_HALFPELREFINE8,
24
25
26XVID_ME_ADVANCEDDIAMOND16|XVID_ME_HALFPELREFINE16|
27XVID_ME_ADVANCEDDIAMOND8|XVID_ME_HALFPELREFINE8|
28XVID_ME_CHROMA_PVOP|XVID_ME_CHROMA_BVOP,
29
30
31XVID_ME_ADVANCEDDIAMOND16|XVID_ME_HALFPELREFINE16|
32XVID_ME_ADVANCEDDIAMOND8|XVID_ME_HALFPELREFINE8|
33XVID_ME_CHROMA_PVOP|XVID_ME_CHROMA_BVOP,
34
35
36XVID_ME_ADVANCEDDIAMOND16|XVID_ME_HALFPELREFINE16|XVID_ME_EXTSEARCH16|
37XVID_ME_ADVANCEDDIAMOND8|XVID_ME_HALFPELREFINE8|XVID_ME_EXTSEARCH8|
38XVID_ME_CHROMA_PVOP|XVID_ME_CHROMA_BVOP,
39
40};
41#defineME_ELEMENTS(sizeof(motion_presets)/sizeof(motion_presets[0]))
42
43staticconstintvop_presets[]={
44
450,
46
47
480,
49
50
51XVID_VOP_HALFPEL,
52
53
54XVID_VOP_HALFPEL|XVID_VOP_INTER4V,
55
56
57XVID_VOP_HALFPEL|XVID_VOP_INTER4V,
58
59
60XVID_VOP_HALFPEL|XVID_VOP_INTER4V|
61XVID_VOP_TRELLISQUANT,
62
63
64XVID_VOP_HALFPEL|XVID_VOP_INTER4V|
65XVID_VOP_TRELLISQUANT|XVID_VOP_HQACPRED,
66
67};
68#defineVOP_ELEMENTS(sizeof(vop_presets)/sizeof(vop_presets[0]))
69
70//////////////////////////////////////////////////////////////////////////
71#defineMAX_ZONES64
72
73
74#defineABS_MAXFRAMENR9999
75
76staticintARG_STATS=0;
77staticintARG_DUMP=0;
78staticintARG_LUMIMASKING=0;
79staticintARG_BITRATE=0;
80staticintARG_SINGLE=0;
81staticchar*ARG_PASS1=0;
82staticchar*ARG_PASS2=0;
83staticintARG_QUALITY=ME_ELEMENTS-1;
84staticfloatARG_FRAMERATE=25.00f;
85staticintARG_MAXFRAMENR=ABS_MAXFRAMENR;
86staticintARG_MAXKEYINTERVAL=0;
87staticchar*ARG_INPUTFILE=NULL;
88staticintARG_INPUTTYPE=0;
89staticintARG_SAVEMPEGSTREAM=0;
90staticintARG_SAVEINDIVIDUAL=0;
91staticchar*ARG_OUTPUTFILE=NULL;
92
93staticintARG_BQRATIO=150;
94staticintARG_BQOFFSET=100;
95staticintARG_MAXBFRAMES=0;
96staticintARG_PACKED=0;
97
98staticintARG_VOPDEBUG=0;
99staticintARG_GMC=0;
100staticintARG_INTERLACING=0;
101staticintARG_QPEL=0;
102staticintARG_CLOSED_GOP=0;
103
104#ifndefREAD_PNM
105#defineIMAGE_SIZE(x,y)((x)*(y)*3/2)
106#else
107#defineIMAGE_SIZE(x,y)((x)*(y)*3)
108#endif
109
110#defineMAX(A,B)(((A)>(B))?(A):(B))
111#defineSMALL_EPS(1e-10)
112
113#defineSWAP(a)((((a)&0x000000ff)<<24)|(((a)&0x0000ff00)<<8)|
114(((a)&0x00ff0000)>>8)|(((a)&0xff000000)>>24))
115
116
117//////////////////////////////////////////////////////////////////////////
118
119
120voidXvid_Encoder::Close(){
121intxerr;
122NVMutexLocklock(_lock);
123
124_closed=true;
125
126xerr=xvid_encore(_enc_handle,XVID_ENC_DESTROY,NULL,NULL);
127
128}
129
130voidXvid_Encoder::xvid_global_init(){
131
134xvid_gbl_init_txvid_gbl_init;
135memset(&xvid_gbl_init,0,sizeof(xvid_gbl_init));
136xvid_gbl_init.version=XVID_VERSION;
137xvid_gbl_init.cpu_flags=XVID_CPU_FORCE;
138
139xvid_global(NULL,XVID_GBL_INIT,&xvid_gbl_init,NULL);
140}
141
142boolXvid_Encoder::Open(){
143intxerr;
144xvid_enc_create_txvid_enc_create;
145_closed=false;
146
149memset(&xvid_enc_create,0,sizeof(xvid_enc_create));
150xvid_enc_create.version=XVID_VERSION;
151
152
153xvid_enc_create.width=GetEncodeInfo().width;
154xvid_enc_create.height=GetEncodeInfo().height;
155xvid_enc_create.profile=XVID_PROFILE_AS_L4;
156
157
158
165
166
167
168xvid_enc_create.num_threads=0;
169
170
171xvid_enc_create.fincr=1;
172xvid_enc_create.fbase=(int)10;
173
174xvid_enc_create.max_key_interval=(int)-1;//--default10s
175
176xvid_enc_create.max_bframes=ARG_MAXBFRAMES;
177xvid_enc_create.bquant_ratio=ARG_BQRATIO;
178xvid_enc_create.bquant_offset=ARG_BQOFFSET;
179
180
181xvid_enc_create.frame_drop_ratio=0;
182
183xvid_enc_create.global=0;
184
185if(ARG_PACKED)
186xvid_enc_create.global|=XVID_GLOBAL_PACKED;
187
188if(ARG_CLOSED_GOP)
189xvid_enc_create.global|=XVID_GLOBAL_CLOSED_GOP;
190
191if(ARG_STATS)
192xvid_enc_create.global|=XVID_GLOBAL_EXTRASTATS_ENABLE;
193
194
195xerr=xvid_encore(NULL,XVID_ENC_CREATE,&xvid_enc_create,NULL);
196_enc_handle=xvid_enc_create.handle;
197returntrue;
198}
199
200voidXvid_Encoder::encode(void*data,unsignedintsize){
201intret;
202_lock.Lock();
203if(_closed){
204_lock.Unlock();
205return;
206}
207ret=xvid_enc((unsignedchar*)data,(unsignedchar*)_bitstream);
208_lock.Unlock();
209if(ret>0)
210_enc_info.after_encode(_bitstream,(unsignedint)ret,_enc_info.user);
211
212}
213
214
217intXvid_Encoder::xvid_enc(unsignedchar*image,unsignedchar*bitstream)
218{
219intret;
220xvid_enc_frame_txvid_enc_frame;
221xvid_enc_stats_txvid_enc_stats;
222
223
224memset(&xvid_enc_frame,0,sizeof(xvid_enc_frame));
225xvid_enc_frame.version=XVID_VERSION;
226
227memset(&xvid_enc_stats,0,sizeof(xvid_enc_stats));
228xvid_enc_stats.version=XVID_VERSION;
229
230
231xvid_enc_frame.bitstream=bitstream;
232xvid_enc_frame.length=-1;
233
234
235xvid_enc_frame.input.plane[0]=image;
236xvid_enc_frame.input.csp=XVID_CSP_BGR;
237xvid_enc_frame.input.stride[0]=_enc_info.width*3;
238
239
240
241xvid_enc_frame.vol_flags=0;
242
243
244xvid_enc_frame.vop_flags=vop_presets[ARG_QUALITY-2];
245
246
247xvid_enc_frame.type=XVID_TYPE_AUTO;
248
249
250xvid_enc_frame.quant=0;
251
252
253xvid_enc_frame.motion=motion_presets[ARG_QUALITY-2];
254
255
256xvid_enc_frame.quant_intra_matrix=NULL;
257xvid_enc_frame.quant_inter_matrix=NULL;
258
259
260ret=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
271return(ret);
272}
273
274
275