FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
hscale.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Pedro Arthur <bygrandao@gmail.com>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "swscale_internal.h"
22 
23 static int lum_h_scale(SwsContext *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
24 {
25  FilterContext *instance = desc->instance;
26  int srcW = desc->src->width;
27  int dstW = desc->dst->width;
28  int xInc = instance->xInc;
29 
30  int i;
31  for (i = 0; i < sliceH; ++i) {
32  uint8_t ** src = desc->src->plane[0].line;
33  uint8_t ** dst = desc->dst->plane[0].line;
34  int src_pos = sliceY+i - desc->src->plane[0].sliceY;
35  int dst_pos = sliceY+i - desc->dst->plane[0].sliceY;
36 
37 
38  if (c->hyscale_fast) {
39  c->hyscale_fast(c, (int16_t*)dst[dst_pos], dstW, src[src_pos], srcW, xInc);
40  } else {
41  c->hyScale(c, (int16_t*)dst[dst_pos], dstW, (const uint8_t *)src[src_pos], instance->filter,
42  instance->filter_pos, instance->filter_size);
43  }
44 
45  if (c->lumConvertRange)
46  c->lumConvertRange((int16_t*)dst[dst_pos], dstW);
47 
48  desc->dst->plane[0].sliceH += 1;
49 
50  if (desc->alpha) {
51  src = desc->src->plane[3].line;
52  dst = desc->dst->plane[3].line;
53 
54  src_pos = sliceY+i - desc->src->plane[3].sliceY;
55  dst_pos = sliceY+i - desc->dst->plane[3].sliceY;
56 
57  desc->dst->plane[3].sliceH += 1;
58 
59  if (c->hyscale_fast) {
60  c->hyscale_fast(c, (int16_t*)dst[dst_pos], dstW, src[src_pos], srcW, xInc);
61  } else {
62  c->hyScale(c, (int16_t*)dst[dst_pos], dstW, (const uint8_t *)src[src_pos], instance->filter,
63  instance->filter_pos, instance->filter_size);
64  }
65  }
66  }
67 
68  return sliceH;
69 }
70 
71 static int lum_convert(SwsContext *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
72 {
73  int srcW = desc->src->width;
74  ColorContext * instance = desc->instance;
75  uint32_t * pal = instance->pal;
76  int i;
77 
78  desc->dst->plane[0].sliceY = sliceY;
79  desc->dst->plane[0].sliceH = sliceH;
80  desc->dst->plane[3].sliceY = sliceY;
81  desc->dst->plane[3].sliceH = sliceH;
82 
83  for (i = 0; i < sliceH; ++i) {
84  int sp0 = sliceY+i - desc->src->plane[0].sliceY;
85  int sp1 = ((sliceY+i) >> desc->src->v_chr_sub_sample) - desc->src->plane[1].sliceY;
86  const uint8_t * src[4] = { desc->src->plane[0].line[sp0],
87  desc->src->plane[1].line[sp1],
88  desc->src->plane[2].line[sp1],
89  desc->src->plane[3].line[sp0]};
90  uint8_t * dst = desc->dst->plane[0].line[i];
91 
92  if (c->lumToYV12) {
93  c->lumToYV12(dst, src[0], src[1], src[2], srcW, pal);
94  } else if (c->readLumPlanar) {
95  c->readLumPlanar(dst, src, srcW, c->input_rgb2yuv_table);
96  }
97 
98 
99  if (desc->alpha) {
100  dst = desc->dst->plane[3].line[i];
101  if (c->alpToYV12) {
102  c->alpToYV12(dst, src[3], src[1], src[2], srcW, pal);
103  } else if (c->readAlpPlanar) {
104  c->readAlpPlanar(dst, src, srcW, NULL);
105  }
106  }
107  }
108 
109  return sliceH;
110 }
111 
113 {
114  ColorContext * li = av_malloc(sizeof(ColorContext));
115  if (!li)
116  return AVERROR(ENOMEM);
117  li->pal = pal;
118  desc->instance = li;
119 
120  desc->alpha = isALPHA(src->fmt) && isALPHA(dst->fmt);
121  desc->src =src;
122  desc->dst = dst;
123  desc->process = &lum_convert;
124 
125  return 0;
126 }
127 
128 
129 int ff_init_desc_hscale(SwsFilterDescriptor *desc, SwsSlice *src, SwsSlice *dst, uint16_t *filter, int * filter_pos, int filter_size, int xInc)
130 {
131  FilterContext *li = av_malloc(sizeof(FilterContext));
132  if (!li)
133  return AVERROR(ENOMEM);
134 
135  li->filter = filter;
136  li->filter_pos = filter_pos;
137  li->filter_size = filter_size;
138  li->xInc = xInc;
139 
140  desc->instance = li;
141 
142  desc->alpha = isALPHA(src->fmt) && isALPHA(dst->fmt);
143  desc->src = src;
144  desc->dst = dst;
145 
146  desc->process = &lum_h_scale;
147 
148  return 0;
149 }
150 
151 static int chr_h_scale(SwsContext *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
152 {
153  FilterContext *instance = desc->instance;
154  int srcW = FF_CEIL_RSHIFT(desc->src->width, desc->src->h_chr_sub_sample);
155  int dstW = FF_CEIL_RSHIFT(desc->dst->width, desc->dst->h_chr_sub_sample);
156  int xInc = instance->xInc;
157 
158  uint8_t ** src1 = desc->src->plane[1].line;
159  uint8_t ** dst1 = desc->dst->plane[1].line;
160  uint8_t ** src2 = desc->src->plane[2].line;
161  uint8_t ** dst2 = desc->dst->plane[2].line;
162 
163  int src_pos1 = sliceY - desc->src->plane[1].sliceY;
164  int dst_pos1 = sliceY - desc->dst->plane[1].sliceY;
165 
166  int src_pos2 = sliceY - desc->src->plane[2].sliceY;
167  int dst_pos2 = sliceY - desc->dst->plane[2].sliceY;
168 
169  int i;
170  for (i = 0; i < sliceH; ++i) {
171  if (c->hcscale_fast) {
172  c->hcscale_fast(c, (uint16_t*)dst1[dst_pos1+i], (uint16_t*)dst2[dst_pos2+i], dstW, src1[src_pos1+i], src2[src_pos2+i], srcW, xInc);
173  } else {
174  c->hcScale(c, (uint16_t*)dst1[dst_pos1+i], dstW, src1[src_pos1+i], instance->filter, instance->filter_pos, instance->filter_size);
175  c->hcScale(c, (uint16_t*)dst2[dst_pos2+i], dstW, src2[src_pos2+i], instance->filter, instance->filter_pos, instance->filter_size);
176  }
177 
178  if (c->chrConvertRange)
179  c->chrConvertRange((uint16_t*)dst1[dst_pos1+i], (uint16_t*)dst2[dst_pos2+i], dstW);
180 
181  desc->dst->plane[1].sliceH += 1;
182  desc->dst->plane[2].sliceH += 1;
183  }
184  return sliceH;
185 }
186 
187 static int chr_convert(SwsContext *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
188 {
189  int srcW = FF_CEIL_RSHIFT(desc->src->width, desc->src->h_chr_sub_sample);
190  ColorContext * instance = desc->instance;
191  uint32_t * pal = instance->pal;
192 
193  int sp0 = (sliceY - (desc->src->plane[0].sliceY >> desc->src->v_chr_sub_sample)) << desc->src->v_chr_sub_sample;
194  int sp1 = sliceY - desc->src->plane[1].sliceY;
195 
196  int i;
197 
198  desc->dst->plane[1].sliceY = sliceY;
199  desc->dst->plane[1].sliceH = sliceH;
200  desc->dst->plane[2].sliceY = sliceY;
201  desc->dst->plane[2].sliceH = sliceH;
202 
203  for (i = 0; i < sliceH; ++i) {
204  const uint8_t * src[4] = { desc->src->plane[0].line[sp0+i],
205  desc->src->plane[1].line[sp1+i],
206  desc->src->plane[2].line[sp1+i],
207  desc->src->plane[3].line[sp0+i]};
208 
209  uint8_t * dst1 = desc->dst->plane[1].line[i];
210  uint8_t * dst2 = desc->dst->plane[2].line[i];
211  if (c->chrToYV12) {
212  c->chrToYV12(dst1, dst2, src[0], src[1], src[2], srcW, pal);
213  } else if (c->readChrPlanar) {
214  c->readChrPlanar(dst1, dst2, src, srcW, c->input_rgb2yuv_table);
215  }
216  }
217  return sliceH;
218 }
219 
221 {
222  ColorContext * li = av_malloc(sizeof(ColorContext));
223  if (!li)
224  return AVERROR(ENOMEM);
225  li->pal = pal;
226  desc->instance = li;
227 
228  desc->src =src;
229  desc->dst = dst;
230  desc->process = &chr_convert;
231 
232  return 0;
233 }
234 
235 int ff_init_desc_chscale(SwsFilterDescriptor *desc, SwsSlice *src, SwsSlice *dst, uint16_t *filter, int * filter_pos, int filter_size, int xInc)
236 {
237  FilterContext *li = av_malloc(sizeof(FilterContext));
238  if (!li)
239  return AVERROR(ENOMEM);
240 
241  li->filter = filter;
242  li->filter_pos = filter_pos;
243  li->filter_size = filter_size;
244  li->xInc = xInc;
245 
246  desc->instance = li;
247 
248  desc->alpha = isALPHA(src->fmt) && isALPHA(dst->fmt);
249  desc->src = src;
250  desc->dst = dst;
251 
252  desc->process = &chr_h_scale;
253 
254  return 0;
255 }
256 
257 static int no_chr_scale(SwsContext *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
258 {
259  desc->dst->plane[1].sliceY = sliceY + sliceH - desc->dst->plane[1].available_lines;
260  desc->dst->plane[1].sliceH = desc->dst->plane[1].available_lines;
261  desc->dst->plane[2].sliceY = sliceY + sliceH - desc->dst->plane[2].available_lines;
262  desc->dst->plane[2].sliceH = desc->dst->plane[2].available_lines;
263  return 0;
264 }
265 
267 {
268  desc->src = src;
269  desc->dst = dst;
270  desc->alpha = 0;
271  desc->instance = NULL;
272  desc->process = &no_chr_scale;
273  return 0;
274 }
#define NULL
Definition: coverity.c:32
void(* hcscale_fast)(struct SwsContext *c, int16_t *dst1, int16_t *dst2, int dstWidth, const uint8_t *src1, const uint8_t *src2, int srcW, int xInc)
int ff_init_desc_fmt_convert(SwsFilterDescriptor *desc, SwsSlice *src, SwsSlice *dst, uint32_t *pal)
initializes lum pixel format conversion descriptor
Definition: hscale.c:112
int h_chr_sub_sample
horizontal chroma subsampling factor
Struct which holds all necessary data for processing a slice.
static int chr_convert(SwsContext *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
Definition: hscale.c:187
static int lum_h_scale(SwsContext *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
Definition: hscale.c:23
uint8_t
void(* readChrPlanar)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src[4], int width, int32_t *rgb2yuv)
#define av_malloc(s)
uint8_t ** line
line buffer
int alpha
Flag for processing alpha channel.
int v_chr_sub_sample
vertical chroma subsampling factor
void(* lumToYV12)(uint8_t *dst, const uint8_t *src, const uint8_t *src2, const uint8_t *src3, int width, uint32_t *pal)
Unscaled conversion of luma plane to YV12 for horizontal scaler.
SwsSlice * dst
Output slice.
int(* process)(SwsContext *c, struct SwsFilterDescriptor *desc, int sliceY, int sliceH)
Function for processing input slice sliceH lines starting from line sliceY.
uint16_t * filter
#define isALPHA(x)
Definition: swscale-test.c:49
int ff_init_desc_no_chr(SwsFilterDescriptor *desc, SwsSlice *src, SwsSlice *dst)
Definition: hscale.c:266
void(* lumConvertRange)(int16_t *dst, int width)
Color range conversion function for luma plane if needed.
int ff_init_desc_cfmt_convert(SwsFilterDescriptor *desc, SwsSlice *src, SwsSlice *dst, uint32_t *pal)
initializes chr pixel format conversion descriptor
Definition: hscale.c:220
#define AVERROR(e)
Definition: error.h:43
static int lum_convert(SwsContext *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
Definition: hscale.c:71
SwsPlane plane[MAX_SLICE_PLANES]
color planes
void(* chrConvertRange)(int16_t *dst1, int16_t *dst2, int width)
Color range conversion function for chroma planes if needed.
int sliceH
number of lines
int ff_init_desc_hscale(SwsFilterDescriptor *desc, SwsSlice *src, SwsSlice *dst, uint16_t *filter, int *filter_pos, int filter_size, int xInc)
initializes lum horizontal scaling descriptor
Definition: hscale.c:129
static int no_chr_scale(SwsContext *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
Definition: hscale.c:257
#define FF_CEIL_RSHIFT(a, b)
Definition: common.h:57
int ff_init_desc_chscale(SwsFilterDescriptor *desc, SwsSlice *src, SwsSlice *dst, uint16_t *filter, int *filter_pos, int filter_size, int xInc)
initializes chr horizontal scaling descriptor
Definition: hscale.c:235
void(* hcScale)(struct SwsContext *c, int16_t *dst, int dstW, const uint8_t *src, const int16_t *filter, const int32_t *filterPos, int filterSize)
int available_lines
max number of lines that can be hold by this plane
static int chr_h_scale(SwsContext *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
Definition: hscale.c:151
void(* readLumPlanar)(uint8_t *dst, const uint8_t *src[4], int width, int32_t *rgb2yuv)
Functions to read planar input, such as planar RGB, and convert internally to Y/UV/A.
#define src1
Definition: h264pred.c:139
AVS_Value src
Definition: avisynth_c.h:482
Color conversion instance data.
int width
Slice line width.
Struct which defines a slice of an image to be scaled or a output for a scaled slice.
void * instance
Filter instance data.
void(* readAlpPlanar)(uint8_t *dst, const uint8_t *src[4], int width, int32_t *rgb2yuv)
static void filter(MpegAudioContext *s, int ch, const short *samples, int incr)
static double c[64]
Scaler instance data.
enum AVPixelFormat fmt
planes pixel format
uint32_t * pal
void(* hyscale_fast)(struct SwsContext *c, int16_t *dst, int dstWidth, const uint8_t *src, int srcW, int xInc)
Scale one horizontal line of input data using a bilinear filter to produce one line of output data...
void(* alpToYV12)(uint8_t *dst, const uint8_t *src, const uint8_t *src2, const uint8_t *src3, int width, uint32_t *pal)
Unscaled conversion of alpha plane to YV12 for horizontal scaler.
void(* chrToYV12)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, const uint8_t *src3, int width, uint32_t *pal)
Unscaled conversion of chroma planes to YV12 for horizontal scaler.
int32_t input_rgb2yuv_table[16+40 *4]
SwsSlice * src
Source slice.
int sliceY
index of first line
void(* hyScale)(struct SwsContext *c, int16_t *dst, int dstW, const uint8_t *src, const int16_t *filter, const int32_t *filterPos, int filterSize)
Scale one horizontal line of input data using a filter over the input lines, to produce one (differen...