~ubuntu-branches/ubuntu/hardy/avidemux/hardy

« back to all changes in this revision

Viewing changes to avidemux/ADM_videoFilter/ADM_vidResampleFPS.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Matvey Kozhev
  • Date: 2007-12-18 13:53:04 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20071218135304-cdqec2lg2bglyz15
Tags: 1:2.4~preview3-0.0ubuntu1
* Upload to Ubuntu. (LP: #163287, LP: #126572)
* debian/changelog: re-added Ubuntu releases.
* debian/control:
  - Require debhelper >= 5.0.51 (for dh_icons) and imagemagick.
  - Build-depend on libsdl1.2-dev instead of libsdl-dev.
  - Build against newer libx264-dev. (LP: #138854)
  - Removed libamrnb-dev, not in Ubuntu yet.
* debian/rules:
  - Install all icon sizes, using convert (upstream installs none).
  - Added missing calls to dh_installmenu, dh_installman, dh_icons and
    dh_desktop.
* debian/menu, debian/avidemux-qt.menu:
  - Corrected package and executable names.
* debian/avidemux-common.install: Install icons.
* debian/avidemux.common.manpages: Install man/avidemux.1.
* debian/links, debian/avidemux-cli.links, debian/avidemux-gtk.links:
  - Link manpages to avidemux.1.gz.
* debian/install, debian/avidemux-qt.install, debian/avidemux-gtk.desktop,
  debian/avidemux-qt.desktop: Install desktop files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
                          Resample fps
 
3
                             -------------------
 
4
    begin                : Wed Nov 6 2002
 
5
    copyright            : (C) 2002 by mean
 
6
    email                : fixounet@free.fr
 
7
 ***************************************************************************/
 
8
 
 
9
/***************************************************************************
 
10
 *                                                                         *
 
11
 *   This program is free software; you can redistribute it and/or modify  *
 
12
 *   it under the terms of the GNU General Public License as published by  *
 
13
 *   the Free Software Foundation; either version 2 of the License, or     *
 
14
 *   (at your option) any later version.                                   *
 
15
 *                                                                         *
 
16
 ***************************************************************************/
 
17
 
 
18
#include <stdio.h>
 
19
#include <math.h>
 
20
 
 
21
#include <stdlib.h>
 
22
#include <string.h>
 
23
#include <ADM_assert.h>
 
24
 
 
25
#include "config.h"
 
26
#include "fourcc.h"
 
27
#include "avio.hxx"
 
28
#include "config.h"
 
29
#include "avi_vars.h"
 
30
#ifdef HAVE_ENCODER
 
31
 
 
32
 
 
33
#include "ADM_toolkit/toolkit.hxx"
 
34
#include "ADM_editor/ADM_edit.hxx"
 
35
#include "ADM_video/ADM_genvideo.hxx"
 
36
#include "ADM_filter/video_filters.h"
 
37
#include "ADM_userInterfaces/ADM_commonUI/DIA_enter.h"
 
38
#include "ADM_video/ADM_cache.h"
 
39
#include "ADM_osSupport/ADM_cpuCap.h"
 
40
#include "admmangle.h"
 
41
 
 
42
#include "ADM_userInterfaces/ADM_commonUI/DIA_factory.h"
 
43
 
 
44
static FILTER_PARAM ResampParam={2,{"newfps","use_linear"}};
 
45
typedef struct FPS_Param
 
46
{
 
47
  uint32_t  newfps; 
 
48
  uint32_t  use_linear;
 
49
}FPS_Param;
 
50
class  ADMVideoResampleFPS:public AVDMGenericVideoStream
 
51
{
 
52
 
 
53
  protected:
 
54
    AVDMGenericVideoStream  *_in;           
 
55
    virtual char            *printConf(void);
 
56
            FPS_Param       *_param;    
 
57
            VideoCache      *vidCache; 
 
58
  public:
 
59
                
 
60
                        ADMVideoResampleFPS(  AVDMGenericVideoStream *in,CONFcouple *setup);
 
61
                        ADMVideoResampleFPS(  AVDMGenericVideoStream *in,uint32_t target1000);
 
62
    virtual             ~ADMVideoResampleFPS();
 
63
    virtual uint8_t     configure(AVDMGenericVideoStream *in);
 
64
    virtual uint8_t     getFrameNumberNoAlloc(uint32_t frame, uint32_t *len,
 
65
                                          ADMImage *data,uint32_t *flags);
 
66
 
 
67
             uint8_t     getCoupledConf( CONFcouple **couples);
 
68
}     ;
 
69
 
 
70
SCRIPT_CREATE(resamplefps_script,ADMVideoResampleFPS,ResampParam);
 
71
BUILD_CREATE(resamplefps_create,ADMVideoResampleFPS);
 
72
 
 
73
AVDMGenericVideoStream *createResampleFps(AVDMGenericVideoStream *in,uint32_t targetfps1000)
 
74
{
 
75
  return new ADMVideoResampleFPS(in,targetfps1000);
 
76
}
 
77
 
 
78
uint8_t ADMVideoResampleFPS::configure(AVDMGenericVideoStream *in)
 
79
{
 
80
  float f=_param->newfps; 
 
81
  f/=1000;
 
82
  
 
83
  _in=in;
 
84
  
 
85
    diaElemFloat fps(&f,QT_TR_NOOP("_New frame rate:"),1,200.);
 
86
    diaElemToggle blend(&(_param->use_linear),QT_TR_NOOP("_Blend"));
 
87
    
 
88
    diaElem *elems[2]={&fps,&blend};
 
89
  
 
90
    if( diaFactoryRun(QT_TR_NOOP("Resample fps"),2,elems))
 
91
    {
 
92
        f*=1000;
 
93
      _param->newfps=(uint32_t)floor(f+0.4); 
 
94
      _info.fps1000=_param->newfps;
 
95
      return 1;
 
96
    }
 
97
    return 0;
 
98
}
 
99
char *ADMVideoResampleFPS::printConf( void )
 
100
{
 
101
  static char buf[50];
 
102
        
 
103
  sprintf((char *)buf," Resample to %2.2f fps (blend:%d)",(double)_param->newfps/1000.,
 
104
                _param->use_linear);
 
105
  return buf;
 
106
}
 
107
 
 
108
ADMVideoResampleFPS::ADMVideoResampleFPS(  AVDMGenericVideoStream *in,uint32_t target)
 
109
{
 
110
 
 
111
  _in=in;         
 
112
  memcpy(&_info,_in->getInfo(),sizeof(_info));    
 
113
  _info.encoding=1; 
 
114
  _param=new  FPS_Param;
 
115
   
 
116
    _param->newfps =target;                
 
117
    _param->use_linear=1;
 
118
 
 
119
  double newlength;
 
120
  
 
121
  newlength=_info.nb_frames;
 
122
  newlength/=_info.fps1000;
 
123
  newlength*=_param->newfps;
 
124
  _info.nb_frames=(uint32_t)floor(newlength);
 
125
  _info.fps1000=_param->newfps;
 
126
  printf("[Resample FPS] %u -> %u\n",_in->getInfo()->nb_frames,_info.nb_frames);
 
127
  vidCache=new VideoCache(3,_in);
 
128
 
 
129
}
 
130
 
 
131
ADMVideoResampleFPS::ADMVideoResampleFPS(  AVDMGenericVideoStream *in,CONFcouple *couples)
 
132
{
 
133
  
 
134
  _in=in;         
 
135
  memcpy(&_info,_in->getInfo(),sizeof(_info));    
 
136
  _info.encoding=1; 
 
137
  _param=new  FPS_Param;
 
138
   
 
139
  if(couples)
 
140
  {                 
 
141
    GET(newfps);    
 
142
    GET(use_linear); 
 
143
  }
 
144
  else
 
145
  {
 
146
    _param->newfps =_info.fps1000;                
 
147
    _param->use_linear=0;
 
148
  }      
 
149
 
 
150
  double newlength;
 
151
  
 
152
  newlength=_info.nb_frames;
 
153
  newlength/=_info.fps1000;
 
154
  newlength*=_param->newfps;
 
155
  _info.nb_frames=(uint32_t)floor(newlength);
 
156
  _info.fps1000=_param->newfps;
 
157
  vidCache=new VideoCache(3,_in);
 
158
  
 
159
}
 
160
ADMVideoResampleFPS::~ADMVideoResampleFPS()
 
161
{
 
162
  delete _param;
 
163
  delete vidCache;
 
164
  
 
165
}
 
166
uint8_t ADMVideoResampleFPS::getCoupledConf( CONFcouple **couples)
 
167
{
 
168
  ADM_assert(_param);
 
169
  *couples=new CONFcouple(2);
 
170
 
 
171
 
 
172
                CSET(newfps);
 
173
                CSET(use_linear);
 
174
                return 1;
 
175
}
 
176
#if (defined( ARCH_X86)  || defined(ARCH_X86_64))
 
177
static uint64_t low,high;
 
178
static void blendMMX(uint8_t *src, uint8_t *src2, uint8_t *dst, uint8_t alpha, uint8_t beta,uint32_t count)
 
179
{
 
180
uint32_t left=count&3;
 
181
#define EXPAND(x) (x)+((x)<<16)+((x)<<32) +((x)<<48)
 
182
        high=alpha;
 
183
        low=beta;
 
184
        high=EXPAND(high);
 
185
        low=EXPAND(low);
 
186
        count>>=2;
 
187
#ifdef GCC_2_95_X
 
188
         __asm__ __volatile__ (
 
189
                                "movq "Mangle(high)", %mm0\n"
 
190
                                "movq "Mangle(low)",  %mm1\n"                                
 
191
                                "pxor %mm7        ,  %mm7\n"
 
192
                                :: );
 
193
#else
 
194
         __asm__ __volatile__ (
 
195
                                "movq "Mangle(high)", %%mm0\n"
 
196
                                "movq "Mangle(low)",  %%mm1\n"                                
 
197
                                "pxor %%mm7        ,  %%mm7\n"
 
198
                                :: );
 
199
#endif
 
200
 
 
201
        while(count>0)
 
202
        {
 
203
                __asm__ __volatile__ (
 
204
                               
 
205
                                "movd      (%0),  %%mm2\n"
 
206
                                "movd      (%1),  %%mm3\n"                               
 
207
 
 
208
                                "punpcklbw %%mm7, %%mm2\n"
 
209
                                "punpcklbw %%mm7, %%mm3\n"
 
210
 
 
211
                                "pmullw   %%mm0, %%mm2\n"
 
212
                                "pmullw   %%mm1, %%mm3\n"
 
213
                
 
214
                                "paddw    %%mm3, %%mm2\n"
 
215
 
 
216
                                "psrlw    $8,    %%mm2 \n"
 
217
 
 
218
                                "packuswb %%mm2,%%mm2\n"
 
219
                                "movd     %%mm2, (%2)\n"
 
220
 
 
221
                                :: "r" (src), "r" (src2), "r" (dst) );
 
222
                                
 
223
                src+=4;
 
224
                src2+=4;
 
225
                dst+=4;
 
226
                count--;
 
227
        }
 
228
        __asm__ __volatile__ (
 
229
                                "emms\n"
 
230
                                :: );
 
231
        for(uint32_t i=0;i<left;i++)
 
232
        {
 
233
                dst[i] = ((src[i]*alpha) + (src2[i]*beta))>>8;
 
234
        }
 
235
}
 
236
 
 
237
#endif
 
238
 
 
239
uint8_t ADMVideoResampleFPS::getFrameNumberNoAlloc(uint32_t frame,
 
240
                                             uint32_t *len,
 
241
                                             ADMImage *data,
 
242
                                             uint32_t *flags)
 
243
{
 
244
  ADMImage *mysrc1=NULL;
 
245
  ADMImage *mysrc2=NULL;
 
246
 
 
247
  if(frame>=_info.nb_frames) return 0;
 
248
  // read uncompressed frame
 
249
  
 
250
  // What frame are we seeking ?
 
251
  double f;
 
252
  uint32_t page=_info.width*_info.height;
 
253
  
 
254
  f=frame;
 
255
  f*=_in->getInfo()->fps1000;
 
256
  f/=_param->newfps;
 
257
  
 
258
  if(!_param->use_linear)
 
259
  {
 
260
      uint32_t nw;
 
261
      
 
262
      nw=(uint32_t)floor(f+0.4);
 
263
      if(nw>_in->getInfo()->nb_frames-1)
 
264
        nw=_in->getInfo()->nb_frames-1;
 
265
    
 
266
      mysrc1=vidCache->getImage(nw);
 
267
      if(!mysrc1) return 0;
 
268
      
 
269
      memcpy(YPLANE(data),YPLANE(mysrc1),page);
 
270
      memcpy(UPLANE(data),UPLANE(mysrc1),page>>2);
 
271
      memcpy(VPLANE(data),VPLANE(mysrc1),page>>2);
 
272
    
 
273
      vidCache->unlockAll();
 
274
      
 
275
      return 1;
 
276
  }
 
277
  /* With linear blending */
 
278
  uint32_t nw;
 
279
  uint8_t lowweight;
 
280
  uint8_t highweight;
 
281
  
 
282
  double diff;
 
283
  
 
284
  nw=(uint32_t)floor(f);
 
285
  diff=f-floor(f);
 
286
  highweight = (uint8_t)floor(diff*256);
 
287
  lowweight = 256 - highweight;
 
288
 
 
289
  if(nw>=_in->getInfo()->nb_frames-1)
 
290
    {
 
291
      printf("[ResampleFps] In %u Out %u\n",frame,nw);
 
292
      nw=_in->getInfo()->nb_frames-1;
 
293
      highweight=0;
 
294
    }
 
295
  //printf("New:%lu old:%lu\n",frame,nw);
 
296
 
 
297
  if(highweight == 0)
 
298
    {
 
299
      mysrc1=vidCache->getImage(nw);  
 
300
      if(!mysrc1) return 0;
 
301
      
 
302
      memcpy(YPLANE(data),YPLANE(mysrc1),page);
 
303
      memcpy(UPLANE(data),UPLANE(mysrc1),page>>2);
 
304
      memcpy(VPLANE(data),VPLANE(mysrc1),page>>2);
 
305
      
 
306
      vidCache->unlockAll();
 
307
    }
 
308
  else
 
309
    {
 
310
      mysrc1=vidCache->getImage(nw);
 
311
      mysrc2=vidCache->getImage(nw+1);
 
312
      if(!mysrc1 || !mysrc2) return 0;
 
313
      
 
314
      uint8_t *out, *in1, *in2;
 
315
      uint32_t count;
 
316
      uint32_t idx;
 
317
      
 
318
      out = YPLANE(data);
 
319
      in1 = YPLANE(mysrc1);
 
320
      in2 = YPLANE(mysrc2);
 
321
        
 
322
      count = page;
 
323
 
 
324
#if (defined( ARCH_X86)  || defined(ARCH_X86_64))
 
325
        if(CpuCaps::hasMMX())
 
326
                blendMMX(in1,in2,out,lowweight,highweight,(count*3)>>1);
 
327
        else
 
328
#endif
 
329
      {
 
330
      for(idx = 0; idx < count; ++idx)
 
331
        out[idx] = ((in1[idx]*lowweight) + (in2[idx]*highweight))>>8;
 
332
 
 
333
      out = UPLANE(data);
 
334
      in1 = UPLANE(mysrc1);
 
335
      in2 = UPLANE(mysrc2);
 
336
      count = page>>2;
 
337
 
 
338
      for(idx = 0; idx < count; ++idx)
 
339
        out[idx] = ((in1[idx]*lowweight) + (in2[idx]*highweight))>>8;      
 
340
 
 
341
 
 
342
      out = VPLANE(data);
 
343
      in1 = VPLANE(mysrc1);
 
344
      in2 = VPLANE(mysrc2);
 
345
      count = page>>2;
 
346
 
 
347
      for(idx = 0; idx < count; ++idx)
 
348
        out[idx] = ((in1[idx]*lowweight) + (in2[idx]*highweight))>>8;
 
349
      }
 
350
 
 
351
      vidCache->unlockAll();
 
352
    }
 
353
  return 1;
 
354
 
 
355
}
 
356
 
 
357
 
 
358
 
 
359
#endif