145
149
case X264_CSP_YV24: /* specially handled via swapping chroma */
146
150
case X264_CSP_I444: return csp&X264_CSP_HIGH_DEPTH ? PIX_FMT_YUV444P16 : PIX_FMT_YUV444P;
147
151
case X264_CSP_RGB: return csp&X264_CSP_HIGH_DEPTH ? PIX_FMT_RGB48 : PIX_FMT_RGB24;
148
/* the next 3 csps have no equivalent 16bit depth in swscale */
152
case X264_CSP_BGR: return csp&X264_CSP_HIGH_DEPTH ? PIX_FMT_BGR48 : PIX_FMT_BGR24;
153
case X264_CSP_BGRA: return csp&X264_CSP_HIGH_DEPTH ? PIX_FMT_BGRA64 : PIX_FMT_BGRA;
154
/* the next csp has no equivalent 16bit depth in swscale */
149
155
case X264_CSP_NV12: return csp&X264_CSP_HIGH_DEPTH ? PIX_FMT_NONE : PIX_FMT_NV12;
150
case X264_CSP_BGR: return csp&X264_CSP_HIGH_DEPTH ? PIX_FMT_NONE : PIX_FMT_BGR24;
151
case X264_CSP_BGRA: return csp&X264_CSP_HIGH_DEPTH ? PIX_FMT_NONE : PIX_FMT_BGRA;
156
/* the next csp is no supported by swscale at all */
152
158
default: return PIX_FMT_NONE;
162
static int pix_number_of_planes( const AVPixFmtDescriptor *pix_desc )
165
for( int i = 0; i < pix_desc->nb_components; i++ )
167
int plane_plus1 = pix_desc->comp[i].plane + 1;
168
num_planes = X264_MAX( plane_plus1, num_planes );
156
173
static int pick_closest_supported_csp( int csp )
158
175
int pix_fmt = convert_csp_to_pix_fmt( csp );
161
case PIX_FMT_YUV420P16LE:
162
case PIX_FMT_YUV420P16BE:
163
return X264_CSP_I420 | X264_CSP_HIGH_DEPTH;
164
case PIX_FMT_YUV422P:
165
case PIX_FMT_YUYV422:
166
case PIX_FMT_UYVY422:
167
case PIX_FMT_YUVJ422P:
168
return X264_CSP_I422;
169
case PIX_FMT_YUV422P16LE:
170
case PIX_FMT_YUV422P16BE:
171
return X264_CSP_I422 | X264_CSP_HIGH_DEPTH;
172
case PIX_FMT_YUV444P:
173
case PIX_FMT_YUVJ444P:
174
return X264_CSP_I444;
175
case PIX_FMT_YUV444P16LE:
176
case PIX_FMT_YUV444P16BE:
177
return X264_CSP_I444 | X264_CSP_HIGH_DEPTH;
179
case PIX_FMT_RGB565BE:
180
case PIX_FMT_RGB565LE:
181
case PIX_FMT_RGB555BE:
182
case PIX_FMT_RGB555LE:
184
case PIX_FMT_RGB48BE:
185
case PIX_FMT_RGB48LE:
186
return X264_CSP_RGB | X264_CSP_HIGH_DEPTH;
188
case PIX_FMT_BGR565BE:
189
case PIX_FMT_BGR565LE:
190
case PIX_FMT_BGR555BE:
191
case PIX_FMT_BGR555LE:
197
return X264_CSP_BGRA;
200
return X264_CSP_NV12;
202
return X264_CSP_I420;
176
// first determine the base csp
177
int ret = X264_CSP_NONE;
178
const AVPixFmtDescriptor *pix_desc = av_pix_fmt_descriptors+pix_fmt;
179
if( (unsigned)pix_fmt >= PIX_FMT_NB || !pix_desc->name )
182
const char *pix_fmt_name = pix_desc->name;
183
int is_rgb = pix_desc->flags & (PIX_FMT_RGB | PIX_FMT_PAL);
184
int is_bgr = !!strstr( pix_fmt_name, "bgr" );
185
if( is_bgr || is_rgb )
187
if( pix_desc->nb_components == 4 ) // has alpha
197
if( pix_desc->nb_components == 1 || pix_desc->nb_components == 2 ) // no chroma
199
else if( pix_desc->log2_chroma_w && pix_desc->log2_chroma_h ) // reduced chroma width & height
200
ret = (pix_number_of_planes( pix_desc ) == 2) ? X264_CSP_NV12 : X264_CSP_I420;
201
else if( pix_desc->log2_chroma_w ) // reduced chroma width only
202
ret = X264_CSP_I422; // X264_CSP_NV16 is not supported by swscale so don't use it
206
// now determine high depth
207
for( int i = 0; i < pix_desc->nb_components; i++ )
208
if( pix_desc->comp[i].depth_minus1 >= 8 )
209
ret |= X264_CSP_HIGH_DEPTH;
206
213
static int handle_opts( const char **optlist, char **opts, video_info_t *info, resizer_hnd_t *h )
349
356
static int x264_init_sws_context( resizer_hnd_t *h )
359
sws_freeContext( h->ctx );
360
h->ctx = sws_alloc_context();
353
h->ctx = sws_alloc_context();
357
/* set flags that will not change */
358
av_set_int( h->ctx, "sws_flags", h->ctx_flags );
359
av_set_int( h->ctx, "dstw", h->dst.width );
360
av_set_int( h->ctx, "dsth", h->dst.height );
361
av_set_int( h->ctx, "dst_format", h->dst.pix_fmt );
362
av_set_int( h->ctx, "dst_range", h->dst.range );
365
av_set_int( h->ctx, "srcw", h->scale.width );
366
av_set_int( h->ctx, "srch", h->scale.height );
367
av_set_int( h->ctx, "src_format", h->scale.pix_fmt );
368
av_set_int( h->ctx, "src_range", h->scale.range );
364
av_opt_set_int( h->ctx, "sws_flags", h->ctx_flags, 0 );
365
av_opt_set_int( h->ctx, "dstw", h->dst.width, 0 );
366
av_opt_set_int( h->ctx, "dsth", h->dst.height, 0 );
367
av_opt_set_int( h->ctx, "dst_format", h->dst.pix_fmt, 0 );
368
av_opt_set_int( h->ctx, "dst_range", h->dst.range, 0 );
370
av_opt_set_int( h->ctx, "srcw", h->scale.width, 0 );
371
av_opt_set_int( h->ctx, "srch", h->scale.height, 0 );
372
av_opt_set_int( h->ctx, "src_format", h->scale.pix_fmt, 0 );
373
av_opt_set_int( h->ctx, "src_range", h->scale.range, 0 );
370
375
/* FIXME: use the correct matrix coefficients (only YUV -> RGB conversions are supported) */
371
376
sws_setColorspaceDetails( h->ctx,
423
428
/* only in normalization scenarios is the input capable of changing properties */
424
429
h->variable_input = 1;
425
430
h->dst_csp = pick_closest_supported_csp( info->csp );
426
/* now fix the catch-all i420 choice if it does not allow for the current input resolution dimensions. */
427
if( h->dst_csp == X264_CSP_I420 && info->width&1 )
428
h->dst_csp = X264_CSP_I444;
429
if( h->dst_csp == X264_CSP_I420 && info->height&1 )
430
h->dst_csp = X264_CSP_I422;
431
FAIL_IF_ERROR( h->dst_csp == X264_CSP_NONE,
432
"filter get invalid input pixel format %d (colorspace %d)\n", convert_csp_to_pix_fmt( info->csp ), info->csp )
432
434
else if( handle_opts( optlist, opts, info, h ) )