diff options
Diffstat (limited to 'src/plugins/ffmpeg/libavcodec/intrax8dsp.c')
-rw-r--r-- | src/plugins/ffmpeg/libavcodec/intrax8dsp.c | 432 |
1 files changed, 0 insertions, 432 deletions
diff --git a/src/plugins/ffmpeg/libavcodec/intrax8dsp.c b/src/plugins/ffmpeg/libavcodec/intrax8dsp.c deleted file mode 100644 index f90c0fd..0000000 --- a/src/plugins/ffmpeg/libavcodec/intrax8dsp.c +++ /dev/null | |||
@@ -1,432 +0,0 @@ | |||
1 | /* | ||
2 | * This file is part of FFmpeg. | ||
3 | * | ||
4 | * FFmpeg is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * FFmpeg is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with FFmpeg; if not, write to the Free Software | ||
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | |||
19 | /** | ||
20 | * @file intrax8dsp.c | ||
21 | *@brief IntraX8 frame subdecoder image manipulation routines | ||
22 | */ | ||
23 | |||
24 | #include "dsputil.h" | ||
25 | |||
26 | /* | ||
27 | area positions, #3 is 1 pixel only, other are 8 pixels | ||
28 | |66666666| | ||
29 | 3|44444444|55555555| | ||
30 | - -+--------+--------+ | ||
31 | 1 2|XXXXXXXX| | ||
32 | 1 2|XXXXXXXX| | ||
33 | 1 2|XXXXXXXX| | ||
34 | 1 2|XXXXXXXX| | ||
35 | 1 2|XXXXXXXX| | ||
36 | 1 2|XXXXXXXX| | ||
37 | 1 2|XXXXXXXX| | ||
38 | 1 2|XXXXXXXX| | ||
39 | ^-start | ||
40 | */ | ||
41 | |||
42 | #define area1 (0) | ||
43 | #define area2 (8) | ||
44 | #define area3 (8+8) | ||
45 | #define area4 (8+8+1) | ||
46 | #define area5 (8+8+1+8) | ||
47 | #define area6 (8+8+1+16) | ||
48 | |||
49 | /** | ||
50 | Collect statistics and prepare the edge pixels required by the other spatial compensation functions. | ||
51 | |||
52 | * @param src pointer to the beginning of the processed block | ||
53 | * @param dst pointer to emu_edge, edge pixels are stored the way other compensation routines do. | ||
54 | * @param linesize byte offset between 2 vertical pixels in the source image | ||
55 | * @param range pointer to the variable where the edge pixel range is to be stored (max-min values) | ||
56 | * @param psum pointer to the variable where the edge pixel sum is to be stored | ||
57 | * @param edges Informs this routine that the block is on an image border, so it has to interpolate the missing edge pixels. | ||
58 | and some of the edge pixels should be interpolated, the flag has the following meaning: | ||
59 | 1 - mb_x==0 - first block in the row, interpolate area #1,#2,#3; | ||
60 | 2 - mb_y==0 - first row, interpolate area #3,#4,#5,#6; | ||
61 | note: 1|2 - mb_x==mb_y==0 - first block, use 0x80 value for all areas; | ||
62 | 4 - mb_x>= (mb_width-1) last block in the row, interpolate area #5; | ||
63 | */ | ||
64 | static void x8_setup_spatial_compensation(uint8_t *src, uint8_t *dst, int linesize, | ||
65 | int * range, int * psum, int edges){ | ||
66 | uint8_t * ptr; | ||
67 | int sum; | ||
68 | int i; | ||
69 | int min_pix,max_pix; | ||
70 | uint8_t c; | ||
71 | |||
72 | if((edges&3)==3){ | ||
73 | *psum=0x80*(8+1+8+2); | ||
74 | *range=0; | ||
75 | memset(dst,0x80,16+1+16+8); | ||
76 | //this triggers flat_dc for sure. | ||
77 | //flat_dc avoids all (other) prediction modes, but requires dc_level decoding. | ||
78 | return; | ||
79 | } | ||
80 | |||
81 | min_pix=256; | ||
82 | max_pix=-1; | ||
83 | |||
84 | sum=0; | ||
85 | |||
86 | if(!(edges&1)){//(mb_x!=0)//there is previous block on this row | ||
87 | ptr=src-1;//left column, area 2 | ||
88 | for(i=7;i>=0;i--){ | ||
89 | c=*(ptr-1);//area1, same mb as area2, no need to check | ||
90 | dst[area1+i]=c; | ||
91 | c=*(ptr); | ||
92 | |||
93 | sum+=c; | ||
94 | min_pix=FFMIN(min_pix,c); | ||
95 | max_pix=FFMAX(max_pix,c); | ||
96 | dst[area2+i]=c; | ||
97 | |||
98 | ptr+=linesize; | ||
99 | } | ||
100 | } | ||
101 | |||
102 | if(!(edges&2)){ //(mb_y!=0)//there is row above | ||
103 | ptr=src-linesize;//top line | ||
104 | for(i=0;i<8;i++){ | ||
105 | c=*(ptr+i); | ||
106 | sum+=c; | ||
107 | min_pix=FFMIN(min_pix, c); | ||
108 | max_pix=FFMAX(max_pix, c); | ||
109 | } | ||
110 | if(edges&4){//last block on the row? | ||
111 | memset(dst+area5,c,8);//set with last pixel fr | ||
112 | memcpy(dst+area4, ptr, 8); | ||
113 | }else{ | ||
114 | memcpy(dst+area4, ptr, 16);//both area4 and 5 | ||
115 | } | ||
116 | memcpy(dst+area6, ptr-linesize, 8);//area6 always present in the above block | ||
117 | } | ||
118 | //now calculate the stuff we need | ||
119 | if(edges&3){//mb_x==0 || mb_y==0){ | ||
120 | int avg=(sum+4)>>3; | ||
121 | if(edges&1){ //(mb_x==0) {//implies mb_y!=0 | ||
122 | memset(dst+area1,avg,8+8+1);//areas 1,2 and 3 are averaged | ||
123 | }else{//implies y==0 x!=0 | ||
124 | memset(dst+area3,avg, 1+16+8);//areas 3, 4,5,6 | ||
125 | } | ||
126 | sum+=avg*9; | ||
127 | }else{ | ||
128 | uint8_t c=*(src-1-linesize);//the edge pixel, in the top line and left column | ||
129 | dst[area3]=c; | ||
130 | sum+=c; | ||
131 | //edge pixel is not part of min/max | ||
132 | } | ||
133 | (*range) = max_pix - min_pix; | ||
134 | sum += *(dst+area5) + *(dst+area5+1); | ||
135 | *psum = sum; | ||
136 | } | ||
137 | |||
138 | |||
139 | static const uint16_t zero_prediction_weights[64*2] = { | ||
140 | 640, 640, 669, 480, 708, 354, 748, 257, 792, 198, 760, 143, 808, 101, 772, 72, | ||
141 | 480, 669, 537, 537, 598, 416, 661, 316, 719, 250, 707, 185, 768, 134, 745, 97, | ||
142 | 354, 708, 416, 598, 488, 488, 564, 388, 634, 317, 642, 241, 716, 179, 706, 132, | ||
143 | 257, 748, 316, 661, 388, 564, 469, 469, 543, 395, 571, 311, 655, 238, 660, 180, | ||
144 | 198, 792, 250, 719, 317, 634, 395, 543, 469, 469, 507, 380, 597, 299, 616, 231, | ||
145 | 161, 855, 206, 788, 266, 710, 340, 623, 411, 548, 455, 455, 548, 366, 576, 288, | ||
146 | 122, 972, 159, 914, 211, 842, 276, 758, 341, 682, 389, 584, 483, 483, 520, 390, | ||
147 | 110, 1172, 144, 1107, 193, 1028, 254, 932, 317, 846, 366, 731, 458, 611, 499, 499 | ||
148 | }; | ||
149 | |||
150 | static void spatial_compensation_0(uint8_t *src , uint8_t *dst, int linesize){ | ||
151 | int i,j; | ||
152 | int x,y; | ||
153 | unsigned int p;//power divided by 2 | ||
154 | int a; | ||
155 | uint16_t left_sum[2][8]; | ||
156 | uint16_t top_sum[2][8]; | ||
157 | memset(left_sum,0,2*8*sizeof(uint16_t)); | ||
158 | memset( top_sum,0,2*8*sizeof(uint16_t)); | ||
159 | |||
160 | for(i=0;i<8;i++){ | ||
161 | a=src[area2+7-i]<<4; | ||
162 | for(j=0;j<8;j++){ | ||
163 | p=abs(i-j); | ||
164 | left_sum[p&1][j]+= a>>(p>>1); | ||
165 | } | ||
166 | } | ||
167 | |||
168 | for(i=0;i<8;i++){ | ||
169 | a=src[area4+i]<<4; | ||
170 | for(j=0;j<8;j++){ | ||
171 | p=abs(i-j); | ||
172 | top_sum[p&1][j]+= a>>(p>>1); | ||
173 | } | ||
174 | } | ||
175 | for(;i<10;i++){ | ||
176 | a=src[area4+i]<<4; | ||
177 | for(j=5;j<8;j++){ | ||
178 | p=abs(i-j); | ||
179 | top_sum[p&1][j]+= a>>(p>>1); | ||
180 | } | ||
181 | } | ||
182 | for(;i<12;i++){ | ||
183 | a=src[area4+i]<<4; | ||
184 | for(j=7;j<8;j++){ | ||
185 | p=abs(i-j); | ||
186 | top_sum[p&1][j]+= a>>(p>>1); | ||
187 | } | ||
188 | } | ||
189 | |||
190 | for(i=0;i<8;i++){ | ||
191 | top_sum [0][i]+=(top_sum [1][i]*181 + 128 )>>8;//181 is sqrt(2)/2 | ||
192 | left_sum[0][i]+=(left_sum[1][i]*181 + 128 )>>8; | ||
193 | } | ||
194 | for(y=0;y<8;y++){ | ||
195 | for(x=0;x<8;x++){ | ||
196 | dst[x] = ( | ||
197 | (uint32_t)top_sum [0][x]*zero_prediction_weights[y*16+x*2+0] + | ||
198 | (uint32_t)left_sum[0][y]*zero_prediction_weights[y*16+x*2+1] + | ||
199 | 0x8000 | ||
200 | )>>16; | ||
201 | } | ||
202 | dst+=linesize; | ||
203 | } | ||
204 | } | ||
205 | static void spatial_compensation_1(uint8_t *src , uint8_t *dst, int linesize){ | ||
206 | int x,y; | ||
207 | |||
208 | for(y=0;y<8;y++){ | ||
209 | for(x=0;x<8;x++){ | ||
210 | dst[x]=src[area4 + FFMIN(2*y+x+2, 15) ]; | ||
211 | } | ||
212 | dst+=linesize; | ||
213 | } | ||
214 | } | ||
215 | static void spatial_compensation_2(uint8_t *src , uint8_t *dst, int linesize){ | ||
216 | int x,y; | ||
217 | |||
218 | for(y=0;y<8;y++){ | ||
219 | for(x=0;x<8;x++){ | ||
220 | dst[x]=src[area4 +1+y+x]; | ||
221 | } | ||
222 | dst+=linesize; | ||
223 | } | ||
224 | } | ||
225 | static void spatial_compensation_3(uint8_t *src , uint8_t *dst, int linesize){ | ||
226 | int x,y; | ||
227 | |||
228 | for(y=0;y<8;y++){ | ||
229 | for(x=0;x<8;x++){ | ||
230 | dst[x]=src[area4 +((y+1)>>1)+x]; | ||
231 | } | ||
232 | dst+=linesize; | ||
233 | } | ||
234 | } | ||
235 | static void spatial_compensation_4(uint8_t *src , uint8_t *dst, int linesize){ | ||
236 | int x,y; | ||
237 | |||
238 | for(y=0;y<8;y++){ | ||
239 | for(x=0;x<8;x++){ | ||
240 | dst[x]=( src[area4+x] + src[area6+x] + 1 )>>1; | ||
241 | } | ||
242 | dst+=linesize; | ||
243 | } | ||
244 | } | ||
245 | static void spatial_compensation_5(uint8_t *src , uint8_t *dst, int linesize){ | ||
246 | int x,y; | ||
247 | |||
248 | for(y=0;y<8;y++){ | ||
249 | for(x=0;x<8;x++){ | ||
250 | if(2*x-y<0){ | ||
251 | dst[x]=src[area2+9+2*x-y]; | ||
252 | }else{ | ||
253 | dst[x]=src[area4 +x-((y+1)>>1)]; | ||
254 | } | ||
255 | } | ||
256 | dst+=linesize; | ||
257 | } | ||
258 | } | ||
259 | static void spatial_compensation_6(uint8_t *src , uint8_t *dst, int linesize){ | ||
260 | int x,y; | ||
261 | |||
262 | for(y=0;y<8;y++){ | ||
263 | for(x=0;x<8;x++){ | ||
264 | dst[x]=src[area3+x-y]; | ||
265 | } | ||
266 | dst+=linesize; | ||
267 | } | ||
268 | } | ||
269 | static void spatial_compensation_7(uint8_t *src , uint8_t *dst, int linesize){ | ||
270 | int x,y; | ||
271 | |||
272 | for(y=0;y<8;y++){ | ||
273 | for(x=0;x<8;x++){ | ||
274 | if(x-2*y>0){ | ||
275 | dst[x]=( src[area3-1+x-2*y] + src[area3+x-2*y] + 1)>>1; | ||
276 | }else{ | ||
277 | dst[x]=src[area2+8-y +(x>>1)]; | ||
278 | } | ||
279 | } | ||
280 | dst+=linesize; | ||
281 | } | ||
282 | } | ||
283 | static void spatial_compensation_8(uint8_t *src , uint8_t *dst, int linesize){ | ||
284 | int x,y; | ||
285 | |||
286 | for(y=0;y<8;y++){ | ||
287 | for(x=0;x<8;x++){ | ||
288 | dst[x]=( src[area1+7-y] + src[area2+7-y] + 1 )>>1; | ||
289 | } | ||
290 | dst+=linesize; | ||
291 | } | ||
292 | } | ||
293 | static void spatial_compensation_9(uint8_t *src , uint8_t *dst, int linesize){ | ||
294 | int x,y; | ||
295 | |||
296 | for(y=0;y<8;y++){ | ||
297 | for(x=0;x<8;x++){ | ||
298 | dst[x]=src[area2+6-FFMIN(x+y,6)]; | ||
299 | } | ||
300 | dst+=linesize; | ||
301 | } | ||
302 | } | ||
303 | static void spatial_compensation_10(uint8_t *src , uint8_t *dst, int linesize){ | ||
304 | int x,y; | ||
305 | |||
306 | for(y=0;y<8;y++){ | ||
307 | for(x=0;x<8;x++){ | ||
308 | dst[x]=(src[area2+7-y]*(8-x)+src[area4+x]*x+4)>>3; | ||
309 | } | ||
310 | dst+=linesize; | ||
311 | } | ||
312 | } | ||
313 | static void spatial_compensation_11(uint8_t *src , uint8_t *dst, int linesize){ | ||
314 | int x,y; | ||
315 | |||
316 | for(y=0;y<8;y++){ | ||
317 | for(x=0;x<8;x++){ | ||
318 | dst[x]=(src[area2+7-y]*y+src[area4+x]*(8-y)+4)>>3; | ||
319 | } | ||
320 | dst+=linesize; | ||
321 | } | ||
322 | } | ||
323 | |||
324 | static void x8_loop_filter(uint8_t * ptr, const int a_stride, const int b_stride, int quant){ | ||
325 | int i,t; | ||
326 | int p0,p1,p2,p3,p4,p5,p6,p7,p8,p9; | ||
327 | int ql=(quant+10)>>3; | ||
328 | |||
329 | for(i=0; i<8; i++,ptr+=b_stride){ | ||
330 | p0=ptr[-5*a_stride]; | ||
331 | p1=ptr[-4*a_stride]; | ||
332 | p2=ptr[-3*a_stride]; | ||
333 | p3=ptr[-2*a_stride]; | ||
334 | p4=ptr[-1*a_stride]; | ||
335 | p5=ptr[ 0 ]; | ||
336 | p6=ptr[ 1*a_stride]; | ||
337 | p7=ptr[ 2*a_stride]; | ||
338 | p8=ptr[ 3*a_stride]; | ||
339 | p9=ptr[ 4*a_stride]; | ||
340 | |||
341 | t= | ||
342 | (FFABS(p1-p2) <= ql) + | ||
343 | (FFABS(p2-p3) <= ql) + | ||
344 | (FFABS(p3-p4) <= ql) + | ||
345 | (FFABS(p4-p5) <= ql); | ||
346 | if(t>0){//You need at least 1 to be able to reach a total score of 6. | ||
347 | t+= | ||
348 | (FFABS(p5-p6) <= ql) + | ||
349 | (FFABS(p6-p7) <= ql) + | ||
350 | (FFABS(p7-p8) <= ql) + | ||
351 | (FFABS(p8-p9) <= ql) + | ||
352 | (FFABS(p0-p1) <= ql); | ||
353 | if(t>=6){ | ||
354 | int min,max; | ||
355 | |||
356 | min=max=p1; | ||
357 | min=FFMIN(min,p3); max=FFMAX(max,p3); | ||
358 | min=FFMIN(min,p5); max=FFMAX(max,p5); | ||
359 | min=FFMIN(min,p8); max=FFMAX(max,p8); | ||
360 | if(max-min<2*quant){//early stop | ||
361 | min=FFMIN(min,p2); max=FFMAX(max,p2); | ||
362 | min=FFMIN(min,p4); max=FFMAX(max,p4); | ||
363 | min=FFMIN(min,p6); max=FFMAX(max,p6); | ||
364 | min=FFMIN(min,p7); max=FFMAX(max,p7); | ||
365 | if(max-min<2*quant){ | ||
366 | ptr[-2*a_stride]=(4*p2 + 3*p3 + 1*p7 + 4)>>3; | ||
367 | ptr[-1*a_stride]=(3*p2 + 3*p4 + 2*p7 + 4)>>3; | ||
368 | ptr[ 0 ]=(2*p2 + 3*p5 + 3*p7 + 4)>>3; | ||
369 | ptr[ 1*a_stride]=(1*p2 + 3*p6 + 4*p7 + 4)>>3; | ||
370 | continue; | ||
371 | }; | ||
372 | } | ||
373 | } | ||
374 | } | ||
375 | { | ||
376 | int x,x0,x1,x2; | ||
377 | int m; | ||
378 | |||
379 | x0 = (2*p3 - 5*p4 + 5*p5 - 2*p6 + 4)>>3; | ||
380 | if(FFABS(x0) < quant){ | ||
381 | x1=(2*p1 - 5*p2 + 5*p3 - 2*p4 + 4)>>3; | ||
382 | x2=(2*p5 - 5*p6 + 5*p7 - 2*p8 + 4)>>3; | ||
383 | |||
384 | x=FFABS(x0) - FFMIN( FFABS(x1), FFABS(x2) ); | ||
385 | m=p4-p5; | ||
386 | |||
387 | if( x > 0 && (m^x0) <0){ | ||
388 | int32_t sign; | ||
389 | |||
390 | sign=m>>31; | ||
391 | m=(m^sign)-sign;//abs(m) | ||
392 | m>>=1; | ||
393 | |||
394 | x=(5*x)>>3; | ||
395 | |||
396 | if(x>m) x=m; | ||
397 | |||
398 | x=(x^sign)-sign; | ||
399 | |||
400 | ptr[-1*a_stride] -= x; | ||
401 | ptr[ 0] += x; | ||
402 | } | ||
403 | } | ||
404 | } | ||
405 | } | ||
406 | } | ||
407 | |||
408 | static void x8_h_loop_filter(uint8_t *src, int stride, int qscale){ | ||
409 | x8_loop_filter(src, stride, 1, qscale); | ||
410 | } | ||
411 | |||
412 | static void x8_v_loop_filter(uint8_t *src, int stride, int qscale){ | ||
413 | x8_loop_filter(src, 1, stride, qscale); | ||
414 | } | ||
415 | |||
416 | void ff_intrax8dsp_init(DSPContext* dsp, AVCodecContext *avctx) { | ||
417 | dsp->x8_h_loop_filter=x8_h_loop_filter; | ||
418 | dsp->x8_v_loop_filter=x8_v_loop_filter; | ||
419 | dsp->x8_setup_spatial_compensation=x8_setup_spatial_compensation; | ||
420 | dsp->x8_spatial_compensation[0]=spatial_compensation_0; | ||
421 | dsp->x8_spatial_compensation[1]=spatial_compensation_1; | ||
422 | dsp->x8_spatial_compensation[2]=spatial_compensation_2; | ||
423 | dsp->x8_spatial_compensation[3]=spatial_compensation_3; | ||
424 | dsp->x8_spatial_compensation[4]=spatial_compensation_4; | ||
425 | dsp->x8_spatial_compensation[5]=spatial_compensation_5; | ||
426 | dsp->x8_spatial_compensation[6]=spatial_compensation_6; | ||
427 | dsp->x8_spatial_compensation[7]=spatial_compensation_7; | ||
428 | dsp->x8_spatial_compensation[8]=spatial_compensation_8; | ||
429 | dsp->x8_spatial_compensation[9]=spatial_compensation_9; | ||
430 | dsp->x8_spatial_compensation[10]=spatial_compensation_10; | ||
431 | dsp->x8_spatial_compensation[11]=spatial_compensation_11; | ||
432 | } | ||