1 /*
2 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
3 * Copyright (C) 2005 Nikolaj Poroshin <porosh3@psu.ru>
4 * Copyright (c) 2014 Arwa Arif <arwaarif1994@gmail.com>
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23 /**
24 * @file
25 * Fast Simple Post-processing filter
26 * This implementation is based on an algorithm described in
27 * "Aria Nosratinia Embedded Post-Processing for
28 * Enhancement of Compressed Images (1999)"
29 * (http://www.utdallas.edu/~aria/papers/vlsisp99.pdf)
30 * Further, with splitting (I)DCT into horizontal/vertical passes, one of
31 * them can be performed once per block, not per pixel. This allows for much
32 * higher speed.
33 *
34 * Originally written by Michael Niedermayer and Nikolaj for the MPlayer
35 * project, and ported by Arwa Arif for FFmpeg.
36 */
37
44
45 #define OFFSET(x) offsetof(FSPPContext, x)
46 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
53 };
54
56
58 { 0, 48, 12, 60, 3, 51, 15, 63, },
59 { 32, 16, 44, 28, 35, 19, 47, 31, },
60 { 8, 56, 4, 52, 11, 59, 7, 55, },
61 { 40, 24, 36, 20, 43, 27, 39, 23, },
62 { 2, 50, 14, 62, 1, 49, 13, 61, },
63 { 34, 18, 46, 30, 33, 17, 45, 29, },
64 { 10, 58, 6, 54, 9, 57, 5, 53, },
65 { 42, 26, 38, 22, 41, 25, 37, 21, },
66 };
67
69 // values (296) can't be too high
70 // -it causes too big quant dependence
71 // or maybe overflow(check), which results in some flashing
72 71, 296, 295, 237, 71, 40, 38, 19,
73 245, 193, 185, 121, 102, 73, 53, 27,
74 158, 129, 141, 107, 97, 73, 50, 26,
75 102, 116, 109, 98, 82, 66, 45, 23,
76 71, 94, 95, 81, 70, 56, 38, 20,
77 56, 77, 74, 66, 56, 44, 30, 15,
78 38, 53, 50, 45, 38, 30, 21, 11,
79 20, 27, 26, 23, 20, 15, 11, 5
80 };
81
82 //This func reads from 1 slice, 1 and clears 0 & 1
84 ptrdiff_t dst_stride, ptrdiff_t src_stride,
85 ptrdiff_t
width, ptrdiff_t
height, ptrdiff_t log2_scale)
86 {
87 int y, x;
88 #define STORE(pos) \
89 temp = (src[x + pos] + (d[pos] >> log2_scale)) >> (6 - log2_scale); \
90 src[x + pos] = src[x + pos - 8 * src_stride] = 0; \
91 if (temp & 0x100) temp = ~(temp >> 31); \
92 dst[x + pos] = temp;
93
94 for (y = 0; y <
height; y++) {
96 for (x = 0; x <
width; x += 8) {
106 }
107 src += src_stride;
108 dst += dst_stride;
109 }
110 }
111
112 //This func reads from 2 slices, 0 & 2 and clears 2-nd
114 ptrdiff_t dst_stride, ptrdiff_t src_stride,
115 ptrdiff_t
width, ptrdiff_t
height, ptrdiff_t log2_scale)
116 {
117 int y, x;
118 #define STORE2(pos) \
119 temp = (src[x + pos] + src[x + pos + 16 * src_stride] + (d[pos] >> log2_scale)) >> (6 - log2_scale); \
120 src[x + pos + 16 * src_stride] = 0; \
121 if (temp & 0x100) temp = ~(temp >> 31); \
122 dst[x + pos] = temp;
123
124 for (y = 0; y <
height; y++) {
126 for (x = 0; x <
width; x += 8) {
136 }
137 src += src_stride;
138 dst += dst_stride;
139 }
140 }
141
142 static void mul_thrmat_c(int16_t *thr_adr_noq, int16_t *thr_adr,
int q)
143 {
145 for (a = 0; a < 64; a++)
146 thr_adr[a] = q * thr_adr_noq[a];
147 }
148
150 int dst_stride, int src_stride,
152 uint8_t *qp_store,
int qp_stride,
int is_luma)
153 {
154 int x, x0, y, es, qy, t;
155
158 const int qpsh = 4 - p->
hsub * !is_luma;
159 const int qpsv = 4 - p->
vsub * !is_luma;
160
162 int16_t *
block = (int16_t *)block_align;
163 int16_t *block3 = (int16_t *)(block_align + 4 * 8 *
BLOCKSZ);
164
165 memset(block3, 0, 4 * 8 *
BLOCKSZ);
166
167 if (!src || !dst) return;
168
169 for (y = 0; y <
height; y++) {
171 memcpy(p->
src + index, src + y * src_stride, width);
172 for (x = 0; x < 8; x++) {
173 p->
src[index - x - 1] = p->
src[index + x ];
174 p->
src[index + width + x ] = p->
src[index + width - x - 1];
175 }
176 }
177
178 for (y = 0; y < 8; y++) {
179 memcpy(p->
src + ( 7 - y ) * stride, p->
src + ( y + 8 ) * stride, stride);
180 memcpy(p->
src + (height + 8 + y) * stride, p->
src + (height - y + 7) * stride, stride);
181 }
182 //FIXME (try edge emu)
183
184 for (y = 8; y < 24; y++)
185 memset(p->
temp + 8 + y * stride, 0, width *
sizeof(int16_t));
186
187 for (y = step; y < height + 8; y += step) { //step= 1,2
188 const int y1 = y - 8 + step; //l5-7 l4-6;
189 qy = y - 4;
190
191 if (qy > height - 1) qy = height - 1;
192 if (qy < 0) qy = 0;
193
194 qy = (qy >> qpsv) * qp_stride;
195 p->
row_fdct(block, p->
src + y * stride + 2 - (y&1), stride, 2);
196
197 for (x0 = 0; x0 < width + 8 - 8 * (
BLOCKSZ - 1); x0 += 8 * (
BLOCKSZ - 1)) {
198 p->
row_fdct(block + 8 * 8, p->
src + y * stride + 8 + x0 + 2 - (y&1), stride, 2 * (
BLOCKSZ - 1));
199
202 else
203 for (x = 0; x < 8 * (
BLOCKSZ - 1); x += 8) {
204 t = x + x0 - 2; //correct t=x+x0-2-(y&1), but its the same
205
206 if (t < 0) t = 0; //t always < width-2
207
208 t = qp_store[qy + (t >> qpsh)];
210
213 }
214 p->
row_idct(block3 + 0 * 8, p->
temp + (y & 15) * stride + x0 + 2 - (y & 1), stride, 2 * (
BLOCKSZ - 1));
215 memmove(block, block + (
BLOCKSZ - 1) * 64, 8 * 8 *
sizeof(int16_t));
//cycling
216 memmove(block3, block3 + (
BLOCKSZ - 1) * 64, 6 * 8 *
sizeof(int16_t));
217 }
218
219 es = width + 8 - x0; // 8, ...
220 if (es > 8)
221 p->
row_fdct(block + 8 * 8, p->
src + y * stride + 8 + x0 + 2 - (y & 1), stride, (es - 4) >> 2);
222
224 if (es > 3)
225 p->
row_idct(block3 + 0 * 8, p->
temp + (y & 15) * stride + x0 + 2 - (y & 1), stride, es >> 2);
226
227 if (!(y1 & 7) && y1) {
228 if (y1 & 8)
230 dst_stride, stride, width, 8, 5 - p->
log2_count);
231 else
233 dst_stride, stride, width, 8, 5 - p->
log2_count);
234 }
235 }
236
237 if (y & 7) { // height % 8 != 0
238 if (y & 8)
239 p->
store_slice(dst + ((y - 8) & ~7) * dst_stride, p->
temp + 8 + 8 * stride,
240 dst_stride, stride, width, y&7, 5 - p->
log2_count);
241 else
242 p->
store_slice2(dst + ((y - 8) & ~7) * dst_stride, p->
temp + 8 + 0 * stride,
243 dst_stride, stride, width, y&7, 5 - p->
log2_count);
244 }
245 }
246
248 {
249 int_simd16_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
253
254 int16_t *dataptr;
255 int16_t *wsptr;
256 int16_t *threshold;
257 int ctr;
258
260 wsptr = output;
261
262 for (; cnt > 0; cnt -= 2) { //start positions
263 threshold = (int16_t *)thr_adr;//threshold_mtx
264 for (ctr =
DCTSIZE; ctr > 0; ctr--) {
265 // Process columns from input, add to output.
268
271
274
277
278 // Even part of FDCT
279
280 tmp10 = tmp0 + tmp3;
281 tmp13 = tmp0 - tmp3;
282 tmp11 = tmp1 + tmp2;
283 tmp12 = tmp1 - tmp2;
284
285 d0 = tmp10 + tmp11;
286 d4 = tmp10 - tmp11;
287
289 d2 = tmp13 + z1;
290 d6 = tmp13 - z1;
291
292 // Even part of IDCT
293
298 tmp0 += 2;
299 tmp10 = (tmp0 + tmp2) >> 2;
300 tmp11 = (tmp0 - tmp2) >> 2;
301
302 tmp13 = (tmp1 + tmp3) >>2; //+2 ! (psnr decides)
304
305 tmp0 = tmp10 + tmp13; //->temps
306 tmp3 = tmp10 - tmp13; //->temps
307 tmp1 = tmp11 + tmp12; //->temps
308 tmp2 = tmp11 - tmp12; //->temps
309
310 // Odd part of FDCT
311
312 tmp10 = tmp4 + tmp5;
313 tmp11 = tmp5 + tmp6;
314 tmp12 = tmp6 + tmp7;
315
320
321 z11 = tmp7 + z3;
322 z13 = tmp7 - z3;
323
324 d5 = z13 + z2;
325 d3 = z13 - z2;
326 d1 = z11 + z4;
327 d7 = z11 - z4;
328
329 // Odd part of IDCT
330
335
336 //Simd version uses here a shortcut for the tmp5,tmp6,tmp7 == 0
337 z13 = tmp6 + tmp5;
338 z10 = (tmp6 - tmp5) << 1;
339 z11 = tmp4 + tmp7;
340 z12 = (tmp4 - tmp7) << 1;
341
342 tmp7 = (z11 + z13) >> 2; //+2 !
347
348 tmp6 = tmp12 - tmp7;
349 tmp5 = tmp11 - tmp6;
350 tmp4 = tmp10 + tmp5;
351
352 wsptr[
DCTSIZE * 0] += (tmp0 + tmp7);
353 wsptr[
DCTSIZE * 1] += (tmp1 + tmp6);
354 wsptr[
DCTSIZE * 2] += (tmp2 + tmp5);
355 wsptr[
DCTSIZE * 3] += (tmp3 - tmp4);
356 wsptr[
DCTSIZE * 4] += (tmp3 + tmp4);
357 wsptr[
DCTSIZE * 5] += (tmp2 - tmp5);
358 wsptr[
DCTSIZE * 6] = (tmp1 - tmp6);
359 wsptr[
DCTSIZE * 7] = (tmp0 - tmp7);
360 //
361 dataptr++; //next column
362 wsptr++;
363 threshold++;
364 }
365 dataptr += 8; //skip each second start pos
366 wsptr += 8;
367 }
368 }
369
370 static void row_idct_c(int16_t *workspace, int16_t *output_adr, ptrdiff_t output_stride,
int cnt)
371 {
372 int_simd16_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
375 int16_t *outptr;
376 int16_t *wsptr;
377
378 cnt *= 4;
379 wsptr = workspace;
380 outptr = output_adr;
381 for (; cnt > 0; cnt--) {
382 // Even part
383 //Simd version reads 4x4 block and transposes it
384 tmp10 = wsptr[2] + wsptr[3];
385 tmp11 = wsptr[2] - wsptr[3];
386
387 tmp13 = wsptr[0] + wsptr[1];
389
390 tmp0 = tmp10 + tmp13; //->temps
391 tmp3 = tmp10 - tmp13; //->temps
392 tmp1 = tmp11 + tmp12;
393 tmp2 = tmp11 - tmp12;
394
395 // Odd part
396 //Also transpose, with previous:
397 // ---- ---- ||||
398 // ---- ---- idct ||||
399 // ---- ---- ---> ||||
400 // ---- ---- ||||
401 z13 = wsptr[4] + wsptr[5];
402 z10 = wsptr[4] - wsptr[5];
403 z11 = wsptr[6] + wsptr[7];
404 z12 = wsptr[6] - wsptr[7];
405
406 tmp7 = z11 + z13;
408
412
413 tmp6 = (tmp12 << 3) - tmp7;
414 tmp5 = (tmp11 << 3) - tmp6;
415 tmp4 = (tmp10 << 3) + tmp5;
416
417 // Final output stage: descale and write column
418 outptr[0 * output_stride] +=
DESCALE(tmp0 + tmp7, 3);
419 outptr[1 * output_stride] +=
DESCALE(tmp1 + tmp6, 3);
420 outptr[2 * output_stride] +=
DESCALE(tmp2 + tmp5, 3);
421 outptr[3 * output_stride] +=
DESCALE(tmp3 - tmp4, 3);
422 outptr[4 * output_stride] +=
DESCALE(tmp3 + tmp4, 3);
423 outptr[5 * output_stride] +=
DESCALE(tmp2 - tmp5, 3);
424 outptr[6 * output_stride] +=
DESCALE(tmp1 - tmp6, 3);
//no += ?
425 outptr[7 * output_stride] +=
DESCALE(tmp0 - tmp7, 3);
//no += ?
426 outptr++;
427
428 wsptr +=
DCTSIZE;
// advance pointer to next row
429 }
430 }
431
433 {
434 int_simd16_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
437 int16_t *dataptr;
438
439 cnt *= 4;
440 // Pass 1: process rows.
441
443 for (; cnt > 0; cnt--) {
444 tmp0 = pixels[line_size * 0] + pixels[line_size * 7];
445 tmp7 = pixels[line_size * 0] - pixels[line_size * 7];
446 tmp1 = pixels[line_size * 1] + pixels[line_size * 6];
447 tmp6 = pixels[line_size * 1] - pixels[line_size * 6];
448 tmp2 = pixels[line_size * 2] + pixels[line_size * 5];
449 tmp5 = pixels[line_size * 2] - pixels[line_size * 5];
450 tmp3 = pixels[line_size * 3] + pixels[line_size * 4];
451 tmp4 = pixels[line_size * 3] - pixels[line_size * 4];
452
453 // Even part
454
455 tmp10 = tmp0 + tmp3;
456 tmp13 = tmp0 - tmp3;
457 tmp11 = tmp1 + tmp2;
458 tmp12 = tmp1 - tmp2;
459 //Even columns are written first, this leads to different order of columns
460 //in column_fidct(), but they are processed independently, so all ok.
461 //Later in the row_idct() columns readed at the same order.
462 dataptr[2] = tmp10 + tmp11;
463 dataptr[3] = tmp10 - tmp11;
464
466 dataptr[0] = tmp13 + z1;
467 dataptr[1] = tmp13 - z1;
468
469 // Odd part
470
471 tmp10 = (tmp4 + tmp5) << 2;
472 tmp11 = (tmp5 + tmp6) << 2;
473 tmp12 = (tmp6 + tmp7) << 2;
474
479
480 z11 = tmp7 + z3;
481 z13 = tmp7 - z3;
482
483 dataptr[4] = z13 + z2;
484 dataptr[5] = z13 - z2;
485 dataptr[6] = z11 + z4;
486 dataptr[7] = z11 - z4;
487
488 pixels++; // advance pointer to next column
490 }
491 }
492
494 {
503 };
504
506 if (!fmts_list)
509 }
510
512 {
515 const int h =
FFALIGN(inlink->
h + 16, 16);
517
520
524
527
533 }
534
541
542 if (ARCH_X86)
544
545 return 0;
546 }
547
549 {
554
555 int qp_stride = 0;
557 int i, bias;
558 int custom_threshold_m[64];
559
561
562 for (i = 0; i < 64; i++)
//FIXME: tune custom_threshold[] and remove this !
564
565 for (i = 0; i < 8; i++) {
567 |(((uint64_t)custom_threshold_m[i * 8 + 6]) << 16)
568 |(((uint64_t)custom_threshold_m[i * 8 + 0]) << 32)
569 |(((uint64_t)custom_threshold_m[i * 8 + 4]) << 48);
570
572 |(((uint64_t)custom_threshold_m[i * 8 + 3]) << 16)
573 |(((uint64_t)custom_threshold_m[i * 8 + 1]) << 32)
574 |(((uint64_t)custom_threshold_m[i * 8 + 7]) << 48);
575 }
576
579
580 /* if we are not in a constant user quantizer mode and we don't want to use
581 * the quantizers from the B-frames (B-frames often have a higher QP), we
582 * need to save the qp table from the last non B-frame; this is what the
583 * following code block does */
586
589
590 /* if the qp stride is not set, it means the QP are only defined on
591 * a line basis */
592 if (!qp_stride) {
594 h = 1;
595 } else {
596 w = qp_stride;
598 }
601 if (ret < 0) {
603 return ret;
604 }
606 }
607
608 av_assert0(w * h <= fspp->non_b_qp_alloc_size);
610 }
611 }
612
616
617 if (qp_table || fspp->
qp) {
620
621 /* get a new frame if in-place is not possible or if the dimensions
622 * are not multiple of 8 */
624 const int aligned_w =
FFALIGN(inlink->
w, 8);
625 const int aligned_h =
FFALIGN(inlink->
h, 8);
626
628 if (!out) {
631 }
635 }
636
638 inlink->
w, inlink->
h, qp_table, qp_stride, 1);
640 cw, ch, qp_table, qp_stride, 0);
642 cw, ch, qp_table, qp_stride, 0);
643 emms_c();
644 }
645 }
646
647 if (in != out) {
651 inlink->
w, inlink->
h);
653 }
655 }
656
658 {
663 }
664
666 {
671 },
673 };
674
676 {
679 },
681 };
682
691 .priv_class = &fspp_class,
693 };
static const int16_t FIX_1_414213562_A
static void column_fidct_c(int16_t *thr_adr, int16_t *data, int16_t *output, int cnt)
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
uint64_t threshold_mtx_noq[8 *2]
This structure describes decoded (raw) audio or video data.
ptrdiff_t const GLvoid * data
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
static void store_slice2_c(uint8_t *dst, int16_t *src, ptrdiff_t dst_stride, ptrdiff_t src_stride, ptrdiff_t width, ptrdiff_t height, ptrdiff_t log2_scale)
int h
agreed upon image height
#define DECLARE_ALIGNED(n, t, v)
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
uint64_t threshold_mtx[8 *2]
static const short custom_threshold[64]
int8_t * av_frame_get_qp_table(AVFrame *f, int *stride, int *type)
int is_disabled
the enabled state from the last expression evaluation
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
static void filter(FSPPContext *p, uint8_t *dst, uint8_t *src, int dst_stride, int src_stride, int width, int height, uint8_t *qp_store, int qp_stride, int is_luma)
#define THRESHOLD(r, x, t)
void(* row_fdct)(int16_t *data, const uint8_t *pixels, ptrdiff_t line_size, int cnt)
const char * name
Pad name.
#define MULTIPLY16H(x, k)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
void(* mul_thrmat)(int16_t *thr_adr_noq, int16_t *thr_adr, int q)
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
static void row_fdct_c(int16_t *data, const uint8_t *pixels, ptrdiff_t line_size, int cnt)
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range...
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
A filter pad used for either input or output.
A link between two filters.
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
static const AVFilterPad fspp_inputs[]
int width
width and height of the video frame
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
static const AVOption fspp_options[]
void ff_fspp_init_x86(FSPPContext *fspp)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
void(* row_idct)(int16_t *workspace, int16_t *output_adr, ptrdiff_t output_stride, int cnt)
static const uint8_t dither[8][8]
void * priv
private data for use by the filter
AVFILTER_DEFINE_CLASS(fspp)
simple assert() macros that are a bit more flexible than ISO C assert().
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
int w
agreed upon image width
enum AVPictureType pict_type
Picture type of the frame.
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
static int config_input(AVFilterLink *inlink)
static const AVFilterPad outputs[]
int format
agreed upon media format
static const AVFilterPad inputs[]
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) returnNULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt)>2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);returnNULL;}returnac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> in
BYTE int const BYTE int int int height
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
void(* store_slice2)(uint8_t *dst, int16_t *src, ptrdiff_t dst_stride, ptrdiff_t src_stride, ptrdiff_t width, ptrdiff_t height, ptrdiff_t log2_scale)
static av_cold void uninit(AVFilterContext *ctx)
static void store_slice_c(uint8_t *dst, int16_t *src, ptrdiff_t dst_stride, ptrdiff_t src_stride, ptrdiff_t width, ptrdiff_t height, ptrdiff_t log2_scale)
const char * name
Filter name.
static int query_formats(AVFilterContext *ctx)
#define AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
Same as AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, except that the filter will have its filter_frame() c...
AVFilterLink ** outputs
array of pointers to output links
static int ff_norm_qscale(int qscale, int type)
Normalize the qscale factor FIXME the H264 qscale is a log based scale, mpeg1/2 is not...
static enum AVPixelFormat pix_fmts[]
static void row_idct_c(int16_t *workspace, int16_t *output_adr, ptrdiff_t output_stride, int cnt)
void * av_calloc(size_t nmemb, size_t size)
Allocate a block of nmemb * size bytes with alignment suitable for all memory accesses (including vec...
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
void(* store_slice)(uint8_t *dst, int16_t *src, ptrdiff_t dst_stride, ptrdiff_t src_stride, ptrdiff_t width, ptrdiff_t height, ptrdiff_t log2_scale)
GLint GLenum GLboolean GLsizei stride
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
static void mul_thrmat_c(int16_t *thr_adr_noq, int16_t *thr_adr, int q)
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
void(* column_fidct)(int16_t *thr_adr, int16_t *data, int16_t *output, int cnt)
AVFilterContext * dst
dest filter
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
static const AVFilterPad fspp_outputs[]
#define av_malloc_array(a, b)
void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height)
Copy image plane from src to dst.
AVPixelFormat
Pixel format.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
#define AV_CEIL_RSHIFT(a, b)