2
// C++ Implementation: X264 encoder
7
// Author: Mean (fixounet at free dot fr)
8
// I'm afraid we will have to borrow one more time from mplayer
9
// to understand how it works
10
// At least, the interface/x264.h file is clean and simple
11
// That's a beginning.
13
// Copyright: See COPYING file that comes with this distribution
23
#include "ADM_library/default.h"
24
#include "ADM_codecs/ADM_codec.h"
27
#include "ADM_codecs/ADM_x264.h"
33
#include <ADM_assert.h>
35
#define HANDLE ((x264_t *)_handle)
36
#define PICS ((x264_picture_t *)_pic)
39
static x264_param_t param;
40
static myENC_RESULT x_res;
41
//*********************************************
42
// Set the common stuff prior to codec opening
43
// ratecontrol stuff is left to the caller
45
//*********************************************
46
uint8_t X264Encoder::preamble(uint32_t fps1000,ADM_x264Param *zparam)
51
printf("Opening X264\n");
53
param.cpu=0; // Will be slow ...
56
param.i_csp=X264_CSP_I420;
58
param.vui.i_sar_width=_w; // FIXME
59
param.vui.i_sar_height=_h;
61
param.i_fps_num=fps1000;
66
param.i_frame_reference=1; // ref frame like mpeg1/2/4
67
param.i_keyint_max=zparam->maxKf; // Max intra distance
68
param.i_keyint_min=zparam->minKf; // Min intra distance
69
param.i_bframe=zparam->nbBframe; // 2 bframe
70
param.b_cabac=zparam->cabac; // Arith coding on/off
74
xhandle=x264_encoder_open(¶m);
75
if(!xhandle) return 0;
77
_handle=(void *)xhandle;
78
_pic=(void *)new x264_picture_t;
79
printf("X264 init ok\n");
83
// should never be called (pure)
84
//*******************************
85
uint8_t X264Encoder::init( uint32_t val,uint32_t fps1000,ADM_x264Param *param )
89
//*******************************
90
uint8_t X264Encoder::stopEncoder(void )
94
x264_encoder_close(HANDLE);
105
X264Encoder::~X264Encoder()
109
//*******************************
110
//************************************
111
uint8_t X264Encoder::encode( ADMImage *in,
119
x264_picture_t pic_out;
123
memset(_pic,0,sizeof(x264_picture_t));
124
PICS->img.i_csp=X264_CSP_I420;
127
PICS->img.plane[0]=in->data; // Y
128
PICS->img.plane[2]=in->data+_w*_h; // u
129
PICS->img.plane[1]=in->data+((_w*_h*5)>>2); // v
130
PICS->img.i_stride[0]=_w;
131
PICS->img.i_stride[1]=_w>>1;
132
PICS->img.i_stride[2]=_w>>1;
134
PICS->i_type=X264_TYPE_AUTO;
136
if(x264_encoder_encode(HANDLE, &nal, &nbNal, PICS,&pic_out) < 0)
138
printf("Error encoding with x264\n");
144
for(uint32_t i=0;i<nbNal;i++)
147
size+= x264_nal_encode(out + size, &sizemax, 1, &nal[i]);
150
x_res.is_key_frame=0;
151
switch(pic_out.i_type)
153
case X264_TYPE_IDR: //FIXME: Only works if nb ref frame==1
155
x_res.is_key_frame=1;
156
if(flags) *flags=AVI_KEY_FRAME;
159
if(flags) *flags=AVI_P_FRAME;
163
if(flags) *flags=AVI_B_FRAME;
166
printf("X264 :Unknown image type:%d\n",pic_out.i_type);
170
x_res.out_quantizer=pic_out.i_qpplus1;
173
//**************************************
174
uint8_t X264Encoder::getResult( void *ress)
178
res=(myENC_RESULT *)ress;
179
memcpy(res,&x_res,sizeof(myENC_RESULT));
183
//*******************CQ*****************
184
uint8_t X264EncoderCQ::init( uint32_t val,uint32_t fps1000,ADM_x264Param *zparam )
186
memset(¶m,0,sizeof(param));
187
x264_param_default( ¶m );
189
param.rc.i_rc_buffer_size=-1;
190
param.rc.i_qp_constant=val;
191
// should be ~ the same as CQ mode (?)
192
return preamble(fps1000,zparam);
194
X264EncoderCQ::~X264EncoderCQ()
198
//*********************CBR***************
199
uint8_t X264EncoderCBR::init( uint32_t val,uint32_t fps1000,ADM_x264Param *zparam )
201
memset(¶m,0,sizeof(param));
202
x264_param_default( ¶m );
204
param.rc.i_bitrate=val/1000;
205
param.rc.i_rc_buffer_size=val/1000;
206
param.rc.i_rc_init_buffer=(val/1000)>>1;
207
return preamble(fps1000,zparam);
209
X264EncoderCBR::~X264EncoderCBR()
213
//*********************Pass1***************
214
uint8_t X264EncoderPass1::init( uint32_t val,uint32_t fps1000,ADM_x264Param *zparam )
216
memset(¶m,0,sizeof(param));
217
x264_param_default( ¶m );
219
param.rc.i_rc_buffer_size=-1;
220
param.rc.i_qp_constant=2;
222
param.rc.b_stat_write = 1;
223
param.rc.b_stat_read = 0;
224
param.rc.psz_stat_out = "/tmp/x264_log.tmp"; //FIXME
225
return preamble(fps1000,zparam);
227
X264EncoderPass1::~X264EncoderPass1()
231
//*********************Pass1***************
232
uint8_t X264EncoderPass2::init( uint32_t val,uint32_t fps1000,ADM_x264Param *zparam )
234
memset(¶m,0,sizeof(param));
235
x264_param_default( ¶m );
238
param.rc.i_bitrate=val;
239
param.rc.i_rc_buffer_size=val;
240
param.rc.i_rc_init_buffer=val>>1;
242
param.rc.b_stat_write = 0;
243
param.rc.b_stat_read = 1;
246
param.rc.psz_stat_in = "/tmp/x264_log.tmp"; // FIXME
247
return preamble(fps1000,zparam);
249
X264EncoderPass2::~X264EncoderPass2()