xvid 数据编码和解码
由于视频开发的需求,封装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
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, 0 , sizeof (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, 0 , sizeof (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, 0 , sizeof (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 /*
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, 0 , sizeof (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, 0 , sizeof (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, 0 , sizeof (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
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, 0 , sizeof (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, 0 , sizeof (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 = ( int ) 10 ;
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, 0 , sizeof (xvid_enc_frame));
225 xvid_enc_frame.version = XVID_VERSION;
226
227 memset( & xvid_enc_stats, 0 , sizeof (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
275
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, 0 , sizeof (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, 0 , sizeof (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 = ( int ) 10 ;
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, 0 , sizeof (xvid_enc_frame));
225 xvid_enc_frame.version = XVID_VERSION;
226
227 memset( & xvid_enc_stats, 0 , sizeof (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
275