~ubuntu-branches/ubuntu/feisty/avidemux/feisty

« back to all changes in this revision

Viewing changes to avidemux/ADM_codecs/ADM_x264.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Christian Marillat
  • Date: 2005-05-25 13:02:29 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20050525130229-jw94cav0yhmg7vjw
Tags: 1:2.0.40-0.0
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// C++ Implementation: X264 encoder
 
3
//
 
4
// Description: 
 
5
//
 
6
//
 
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.
 
12
//
 
13
// Copyright: See COPYING file that comes with this distribution
 
14
//
 
15
//
 
16
#include "config.h"
 
17
 
 
18
#include <stdio.h>
 
19
#include <stdlib.h>
 
20
#include <string.h>
 
21
#include <math.h>
 
22
 
 
23
#include "ADM_library/default.h"
 
24
#include "ADM_codecs/ADM_codec.h"
 
25
#ifdef USE_X264
 
26
 
 
27
#include "ADM_codecs/ADM_x264.h"
 
28
extern "C"
 
29
{
 
30
        #include "x264.h"
 
31
};        
 
32
 
 
33
#include <ADM_assert.h>
 
34
 
 
35
#define HANDLE ((x264_t *)_handle)                     
 
36
#define PICS ((x264_picture_t *)_pic)                     
 
37
 
 
38
// Yes, ugly FIXME
 
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
 
44
// to initialize
 
45
//*********************************************
 
46
uint8_t   X264Encoder::preamble(uint32_t fps1000,ADM_x264Param *zparam)
 
47
{      
 
48
  
 
49
  x264_t                *xhandle=NULL;
 
50
 
 
51
        printf("Opening X264\n");
 
52
  
 
53
        param.cpu=0; // Will be slow ...
 
54
        param.i_width=_w;
 
55
        param.i_height=_h;
 
56
        param.i_csp=X264_CSP_I420;
 
57
        
 
58
        param.vui.i_sar_width=_w;       // FIXME
 
59
        param.vui.i_sar_height=_h;
 
60
        
 
61
        param.i_fps_num=fps1000;
 
62
        param.i_fps_den=1000;
 
63
        param.i_maxframes=0;
 
64
        if(zparam)
 
65
        {
 
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
 
71
        }
 
72
        
 
73
        
 
74
        xhandle=x264_encoder_open(&param);
 
75
        if(!xhandle) return 0;
 
76
        
 
77
        _handle=(void *)xhandle;
 
78
        _pic=(void *)new x264_picture_t;
 
79
        printf("X264 init ok\n");
 
80
        return 1;
 
81
  
 
82
}
 
83
// should never be called (pure)
 
84
//*******************************
 
85
uint8_t         X264Encoder::init( uint32_t val,uint32_t fps1000,ADM_x264Param *param )
 
86
{
 
87
  ADM_assert(0);
 
88
}
 
89
//*******************************
 
90
uint8_t         X264Encoder::stopEncoder(void )
 
91
{
 
92
  if(_handle)
 
93
  {
 
94
    x264_encoder_close(HANDLE);
 
95
    _handle=NULL;
 
96
  }
 
97
  if(_pic)    
 
98
  {
 
99
    // picture_clean ?
 
100
    delete PICS;
 
101
    _pic=NULL;
 
102
  }
 
103
  
 
104
}
 
105
X264Encoder::~X264Encoder()
 
106
{
 
107
  stopEncoder(); 
 
108
}
 
109
//*******************************
 
110
//************************************
 
111
uint8_t         X264Encoder::encode( ADMImage        *in,
 
112
                                    uint8_t         *out,
 
113
                                    uint32_t        *len,
 
114
                                    uint32_t        *flags)
 
115
{
 
116
  x264_nal_t *nal;
 
117
  int nbNal=0;
 
118
  int sizemax=0;
 
119
  x264_picture_t pic_out;
 
120
  
 
121
        if(flags) *flags=0;
 
122
        
 
123
        memset(_pic,0,sizeof(x264_picture_t));
 
124
        PICS->img.i_csp=X264_CSP_I420;
 
125
        PICS->img.i_plane=3;
 
126
        
 
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;
 
133
        
 
134
        PICS->i_type=X264_TYPE_AUTO;
 
135
        
 
136
        if(x264_encoder_encode(HANDLE, &nal, &nbNal, PICS,&pic_out) < 0) 
 
137
        {
 
138
          printf("Error encoding with x264\n");
 
139
          return 0; 
 
140
        }
 
141
 
 
142
        // Write
 
143
        uint32_t size=0;
 
144
        for(uint32_t i=0;i<nbNal;i++)
 
145
        {
 
146
          sizemax=0xfffffff;;
 
147
          size+= x264_nal_encode(out + size, &sizemax, 1, &nal[i]);          
 
148
        }
 
149
        *len=size;
 
150
        x_res.is_key_frame=0;
 
151
        switch(pic_out.i_type)
 
152
        {
 
153
          case X264_TYPE_IDR:   //FIXME: Only works if nb ref frame==1
 
154
          case X264_TYPE_I:
 
155
                        x_res.is_key_frame=1;            
 
156
                        if(flags) *flags=AVI_KEY_FRAME;
 
157
                        break;
 
158
          case X264_TYPE_P:
 
159
                        if(flags) *flags=AVI_P_FRAME;
 
160
                        break;
 
161
          case X264_TYPE_B:
 
162
          case X264_TYPE_BREF:
 
163
                        if(flags) *flags=AVI_B_FRAME;
 
164
                        break;
 
165
          default:   
 
166
            printf("X264 :Unknown image type:%d\n",pic_out.i_type);
 
167
            //ADM_assert(0);
 
168
          
 
169
        }       
 
170
        x_res.out_quantizer=pic_out.i_qpplus1;        
 
171
        return 1;  
 
172
}
 
173
//**************************************
 
174
uint8_t         X264Encoder::getResult( void *ress)
 
175
{
 
176
  myENC_RESULT *res;
 
177
 
 
178
  res=(myENC_RESULT *)ress;
 
179
  memcpy(res,&x_res,sizeof(myENC_RESULT));
 
180
  return 1;
 
181
 
 
182
}
 
183
//*******************CQ*****************
 
184
uint8_t         X264EncoderCQ::init( uint32_t val,uint32_t fps1000,ADM_x264Param *zparam )
 
185
{
 
186
  memset(&param,0,sizeof(param));
 
187
  x264_param_default( &param );
 
188
 
 
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); 
 
193
}
 
194
X264EncoderCQ::~X264EncoderCQ()
 
195
{
 
196
  stopEncoder(); 
 
197
}
 
198
//*********************CBR***************
 
199
uint8_t         X264EncoderCBR::init( uint32_t val,uint32_t fps1000,ADM_x264Param *zparam )
 
200
{
 
201
  memset(&param,0,sizeof(param));
 
202
  x264_param_default( &param );
 
203
  param.rc.b_cbr=1;
 
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); 
 
208
}
 
209
X264EncoderCBR::~X264EncoderCBR()
 
210
{
 
211
  stopEncoder(); 
 
212
}
 
213
//*********************Pass1***************
 
214
uint8_t         X264EncoderPass1::init( uint32_t val,uint32_t fps1000,ADM_x264Param *zparam )
 
215
{
 
216
  memset(&param,0,sizeof(param));
 
217
  x264_param_default( &param );
 
218
  
 
219
  param.rc.i_rc_buffer_size=-1;
 
220
  param.rc.i_qp_constant=2;  
 
221
  
 
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); 
 
226
}
 
227
X264EncoderPass1::~X264EncoderPass1()
 
228
{
 
229
  stopEncoder(); 
 
230
}
 
231
//*********************Pass1***************
 
232
uint8_t         X264EncoderPass2::init( uint32_t val,uint32_t fps1000,ADM_x264Param *zparam )
 
233
{
 
234
  memset(&param,0,sizeof(param));
 
235
  x264_param_default( &param );
 
236
  
 
237
  param.rc.b_cbr=1;
 
238
  param.rc.i_bitrate=val;  
 
239
  param.rc.i_rc_buffer_size=val;
 
240
  param.rc.i_rc_init_buffer=val>>1;
 
241
  
 
242
  param.rc.b_stat_write = 0;
 
243
  param.rc.b_stat_read = 1;
 
244
  
 
245
  
 
246
  param.rc.psz_stat_in = "/tmp/x264_log.tmp"; // FIXME
 
247
  return preamble(fps1000,zparam); 
 
248
}
 
249
X264EncoderPass2::~X264EncoderPass2()
 
250
{
 
251
  stopEncoder(); 
 
252
}
 
253
 
 
254
//********
 
255
#endif